<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>龙陌的博客</title>
    <meta name="description" content="基于vite为基础搭建的风格脚手架,提供多种模板以便于更高效的解决业务需求！">
    <meta name="generator" content="VitePress v1.0.1">
    <link rel="preload stylesheet" href="/long-press/assets/style.BL65bImA.css" as="style">
    
    <script type="module" src="/long-press/assets/app.CKtEL6mi.js"></script>
    <link rel="preload" href="/long-press/assets/inter-roman-latin.Bu8hRsVA.woff2" as="font" type="font/woff2" crossorigin="">
    <link rel="modulepreload" href="/long-press/assets/chunks/framework.Cp_of1Ge.js">
    <link rel="modulepreload" href="/long-press/assets/chunks/theme.hH2tFlJ7.js">
    <link rel="modulepreload" href="/long-press/assets/chunks/PageInfo.vue_vue_type_script_setup_true_lang.9LRWY4ho.js">
    <link rel="modulepreload" href="/long-press/assets/chunks/dayjs.min.BrPrGVY0.js">
    <link rel="modulepreload" href="/long-press/assets/css3_现代web布局_17.md.BCxBKcNP.lean.js">
    <link rel="icon" type="image/svg+xml" href="logo.ico">
    <meta name="author" content="龙陌">
    <meta name="referrer" content="no-referrer">
    <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
    <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-4c760b95><!--[--><!--]--><!--[--><span tabindex="-1" data-v-16c53dd7></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-16c53dd7> Skip to content </a><!--]--><!----><header class="VPNav" data-v-4c760b95 data-v-0a463f3f><div class="VPNavBar has-sidebar top" data-v-0a463f3f data-v-460dba10><div class="wrapper" data-v-460dba10><div class="container" data-v-460dba10><div class="title" data-v-460dba10><div class="VPNavBarTitle has-sidebar" data-v-460dba10 data-v-ef777607><a class="title" href="/long-press/" data-v-ef777607><!--[--><!--]--><!--[--><img class="VPImage logo" src="/long-press/logo.ico" alt data-v-9cb742f0><!--]--><span data-v-ef777607>龙陌的博客</span><!--[--><!--]--></a></div></div><div class="content" data-v-460dba10><div class="content-body" data-v-460dba10><!--[--><!--]--><div class="VPNavBarSearch search" data-v-460dba10><!----><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><span class="DocSearch-Button-Key">Meta</span><span class="DocSearch-Button-Key">K</span></span></button></div></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-460dba10 data-v-b298d4fd><span id="main-nav-aria-label" class="visually-hidden" data-v-b298d4fd>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>💻 首页</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/guide/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>💡 指南</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/tools/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>🔧 编程工具</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/utils/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>🔧 常用工具类</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/standard/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>📋 前端规范</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/react/React实战,设计模式与最佳实践/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>⭐ React</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/typescript/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>⭐ TypeScript</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/css3/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>⭐ Css3</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/electron/" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>⭐ Electron</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/long-press/linux/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4" tabindex="0" data-v-b298d4fd data-v-5d92c3a7><!--[--><span data-v-5d92c3a7>⭐ Linux</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-460dba10 data-v-815abbf3><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="Switch to dark theme" aria-checked="false" data-v-815abbf3 data-v-34066301 data-v-b6ab5a8a><span class="check" data-v-b6ab5a8a><span class="icon" data-v-b6ab5a8a><!--[--><span class="vpi-sun sun" data-v-34066301></span><span class="vpi-moon moon" data-v-34066301></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-460dba10 data-v-a0947e71 data-v-2fe70121><!--[--><a class="VPSocialLink no-icon" href="https://vitepress.vuejs.org/guide/getting-started" aria-label="github" target="_blank" rel="noopener" data-v-2fe70121 data-v-39684c0a><span class="vpi-social-github" /></a><a class="VPSocialLink no-icon" href="https://space.bilibili.com/248956095" aria-label target="_blank" rel="noopener" data-v-2fe70121 data-v-39684c0a><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="20" height="20"  viewBox="0 0 512 512" >
    <path fill="currentColor" d="M488.6 104.1c16.7 18.1 24.4 39.7 23.3 65.7v202.4c-.4 26.4-9.2 48.1-26.5 65.1c-17.2 17-39.1 25.9-65.5 26.7H92.02c-26.45-.8-48.21-9.8-65.28-27.2C9.682 419.4.767 396.5 0 368.2V169.8c.767-26 9.682-47.6 26.74-65.7C43.81 87.75 65.57 78.77 92.02 78h29.38L96.05 52.19c-5.75-5.73-8.63-13-8.63-21.79c0-8.8 2.88-16.06 8.63-21.797C101.8 2.868 109.1 0 117.9 0s16.1 2.868 21.9 8.603L213.1 78h88l74.5-69.397C381.7 2.868 389.2 0 398 0c8.8 0 16.1 2.868 21.9 8.603c5.7 5.737 8.6 12.997 8.6 21.797c0 8.79-2.9 16.06-8.6 21.79L394.6 78h29.3c26.4.77 48 9.75 64.7 26.1zm-38.8 69.7c-.4-9.6-3.7-17.4-10.7-23.5c-5.2-6.1-14-9.4-22.7-9.8H96.05c-9.59.4-17.45 3.7-23.58 9.8c-6.14 6.1-9.4 13.9-9.78 23.5v194.4c0 9.2 3.26 17 9.78 23.5s14.38 9.8 23.58 9.8H416.4c9.2 0 17-3.3 23.3-9.8c6.3-6.5 9.7-14.3 10.1-23.5V173.8zm-264.3 42.7c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.2 6.3-14 9.5-23.6 9.5c-9.6 0-17.5-3.2-23.6-9.5c-6.1-6.3-9.4-14-9.8-23.2v-33.3c.4-9.1 3.8-16.9 10.1-23.2c6.3-6.3 13.2-9.6 23.3-10c9.2.4 17 3.7 23.3 10zm191.5 0c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.1 6.3-14 9.5-23.6 9.5c-9.6 0-17.4-3.2-23.6-9.5c-7-6.3-9.4-14-9.7-23.2v-33.3c.3-9.1 3.7-16.9 10-23.2c6.3-6.3 14.1-9.6 23.3-10c9.2.4 17 3.7 23.3 10z"></path>
  </svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-460dba10 data-v-b81df352 data-v-603fa601><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-603fa601><span class="vpi-more-horizontal icon" data-v-603fa601></span></button><div class="menu" data-v-603fa601><div class="VPMenu" data-v-603fa601 data-v-61aada2f><!----><!--[--><!--[--><!----><div class="group" data-v-b81df352><div class="item appearance" data-v-b81df352><p class="label" data-v-b81df352>外观</p><div class="appearance-action" data-v-b81df352><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="Switch to dark theme" aria-checked="false" data-v-b81df352 data-v-34066301 data-v-b6ab5a8a><span class="check" data-v-b6ab5a8a><span class="icon" data-v-b6ab5a8a><!--[--><span class="vpi-sun sun" data-v-34066301></span><span class="vpi-moon moon" data-v-34066301></span><!--]--></span></span></button></div></div></div><div class="group" data-v-b81df352><div class="item social-links" data-v-b81df352><div class="VPSocialLinks social-links-list" data-v-b81df352 data-v-2fe70121><!--[--><a class="VPSocialLink no-icon" href="https://vitepress.vuejs.org/guide/getting-started" aria-label="github" target="_blank" rel="noopener" data-v-2fe70121 data-v-39684c0a><span class="vpi-social-github" /></a><a class="VPSocialLink no-icon" href="https://space.bilibili.com/248956095" aria-label target="_blank" rel="noopener" data-v-2fe70121 data-v-39684c0a><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="20" height="20"  viewBox="0 0 512 512" >
    <path fill="currentColor" d="M488.6 104.1c16.7 18.1 24.4 39.7 23.3 65.7v202.4c-.4 26.4-9.2 48.1-26.5 65.1c-17.2 17-39.1 25.9-65.5 26.7H92.02c-26.45-.8-48.21-9.8-65.28-27.2C9.682 419.4.767 396.5 0 368.2V169.8c.767-26 9.682-47.6 26.74-65.7C43.81 87.75 65.57 78.77 92.02 78h29.38L96.05 52.19c-5.75-5.73-8.63-13-8.63-21.79c0-8.8 2.88-16.06 8.63-21.797C101.8 2.868 109.1 0 117.9 0s16.1 2.868 21.9 8.603L213.1 78h88l74.5-69.397C381.7 2.868 389.2 0 398 0c8.8 0 16.1 2.868 21.9 8.603c5.7 5.737 8.6 12.997 8.6 21.797c0 8.79-2.9 16.06-8.6 21.79L394.6 78h29.3c26.4.77 48 9.75 64.7 26.1zm-38.8 69.7c-.4-9.6-3.7-17.4-10.7-23.5c-5.2-6.1-14-9.4-22.7-9.8H96.05c-9.59.4-17.45 3.7-23.58 9.8c-6.14 6.1-9.4 13.9-9.78 23.5v194.4c0 9.2 3.26 17 9.78 23.5s14.38 9.8 23.58 9.8H416.4c9.2 0 17-3.3 23.3-9.8c6.3-6.5 9.7-14.3 10.1-23.5V173.8zm-264.3 42.7c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.2 6.3-14 9.5-23.6 9.5c-9.6 0-17.5-3.2-23.6-9.5c-6.1-6.3-9.4-14-9.8-23.2v-33.3c.4-9.1 3.8-16.9 10.1-23.2c6.3-6.3 13.2-9.6 23.3-10c9.2.4 17 3.7 23.3 10zm191.5 0c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.1 6.3-14 9.5-23.6 9.5c-9.6 0-17.4-3.2-23.6-9.5c-7-6.3-9.4-14-9.7-23.2v-33.3c.3-9.1 3.7-16.9 10-23.2c6.3-6.3 14.1-9.6 23.3-10c9.2.4 17 3.7 23.3 10z"></path>
  </svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-460dba10 data-v-156ee799><span class="container" data-v-156ee799><span class="top" data-v-156ee799></span><span class="middle" data-v-156ee799></span><span class="bottom" data-v-156ee799></span></span></button></div></div></div></div><div class="divider" data-v-460dba10><div class="divider-line" data-v-460dba10></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-4c760b95 data-v-bc5dff2d><div class="container" data-v-bc5dff2d><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-bc5dff2d><span class="vpi-align-left menu-icon" data-v-bc5dff2d></span><span class="menu-text" data-v-bc5dff2d>归档</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-bc5dff2d data-v-fe28bfa1><button data-v-fe28bfa1>返回顶部</button><!----></div></div></div><aside class="VPSidebar" data-v-4c760b95 data-v-e1756f1c><div class="curtain" data-v-e1756f1c></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-e1756f1c><span class="visually-hidden" id="sidebar-aria-label" data-v-e1756f1c> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-e1756f1c><section class="VPSidebarItem level-0 collapsible" data-v-e1756f1c data-v-b147bcc8><div class="item" role="button" tabindex="0" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><h2 class="text" data-v-b147bcc8>现代web布局</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-b147bcc8><span class="vpi-chevron-right caret-icon" data-v-b147bcc8></span></div></div><div class="items" data-v-b147bcc8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/01" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Web 布局技术演进：了解 Web 布局发展史</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/02" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>现代 Web 布局技术术语</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/03" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 布局基础使用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/04" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 布局中的对齐方式</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/05" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 布局中的 flex 属性的基础运用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/06" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 中的计算：通过扩展因子比例来扩展 Flex 项目</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/07" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 中的计算：通过收缩因子比例收缩 Flex 项目</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/08" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>Flexbox 布局中的 flex-basis：谁能决定 Flex 项目的大小？</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/09" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>使用 Flexbox 构建经典布局：10 种经典 Web 布局</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/10" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>10</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-e1756f1c><section class="VPSidebarItem level-0 collapsible" data-v-e1756f1c data-v-b147bcc8><div class="item" role="button" tabindex="0" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><h2 class="text" data-v-b147bcc8>postcss</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-b147bcc8><span class="vpi-chevron-right caret-icon" data-v-b147bcc8></span></div></div><div class="items" data-v-b147bcc8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-b147bcc8 data-v-b147bcc8><div class="item" data-v-b147bcc8><div class="indicator" data-v-b147bcc8></div><a class="VPLink link link" href="/long-press/css3/postcss/postcss-prefix-selector%E5%A2%9E%E5%8A%A0%E7%BB%9F%E4%B8%80%E4%BD%9C%E7%94%A8%E5%9F%9F" data-v-b147bcc8><!--[--><p class="text" data-v-b147bcc8>postcss-prefix-selector增加统一作用域</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-4c760b95 data-v-308553a0><div class="VPDoc has-sidebar has-aside" data-v-308553a0 data-v-e512d8d8><!--[--><!--]--><div class="container" data-v-e512d8d8><div class="aside" data-v-e512d8d8><div class="aside-curtain" data-v-e512d8d8></div><div class="aside-container" data-v-e512d8d8><div class="aside-content" data-v-e512d8d8><div class="VPDocAside" data-v-e512d8d8 data-v-bca3b04c><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-bca3b04c data-v-ff0b6666><div class="content" data-v-ff0b6666><div class="outline-marker" data-v-ff0b6666></div><div class="outline-title" role="heading" aria-level="2" data-v-ff0b6666>本页目录</div><nav aria-labelledby="doc-outline-aria-label" data-v-ff0b6666><span class="visually-hidden" id="doc-outline-aria-label" data-v-ff0b6666> Table of Contents for current page </span><ul class="VPDocOutlineItem root" data-v-ff0b6666 data-v-69d389fc><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-bca3b04c></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-e512d8d8><div class="content-container" data-v-e512d8d8><!--[--><!--]--><main class="main" data-v-e512d8d8><div style="position:relative;" class="vp-doc _long-press_css3_%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80_17" data-v-e512d8d8><div><p>我们花了一节课（《<a href="https://juejin.cn/book/7161370789680250917/section/7160657953932967967" target="_blank" rel="noreferrer">网格布局中的子网格和嵌套网格</a>》）专门介绍了网格布局中的子网格和嵌套网格的基础知识。并且阐述了为什么需要子网格布局。这节课，我将带领大家了解子网格的一些潜在案例，即子网格可用于哪些 Web 中布局中。</p><h2 id="卡片组件的布局" tabindex="-1">卡片组件的布局 <a class="header-anchor" href="#卡片组件的布局" aria-label="Permalink to &quot;卡片组件的布局&quot;">​</a></h2><p>在 Web 布局中，常常会用到卡片组件，子网格来构建卡片组件布局是很有用的。接下来，我们一起来看两种卡片组件的布局。先来看第一种：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/083ae04152f24fd2a9347c2cfb246a1e~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/zYaKmpZ" target="_blank" rel="noreferrer">https://codepen.io/airen/full/zYaKmpZ</a></p></blockquote><p>相邻卡片是在块轴（Block Axis）方向（垂直方向）堆叠的，并且每张卡片都包括：</p><ul><li>标题；</li><li>缩略图；</li><li>描述文本；</li><li>媒体列表。</li></ul><p>它的基本结构如下：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;cards&quot;&gt;&lt;!-- grid --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;&lt;!-- subgrid --&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;标题&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;img src=&quot;&quot; alt=&quot;缩略图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;p&gt;描述文本&lt;/p&gt;</span></span>
<span class="line"><span>        &lt;span&gt;列表1&lt;/span&gt;</span></span>
<span class="line"><span>        &lt;span&gt;列表2&lt;/span&gt;</span></span>
<span class="line"><span>        &lt;span&gt;列表3&lt;/span&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>卡片容器 <code>.cards</code> 分为五列，行随卡片 <code>.card</code> 的数量自动增加：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.cards {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-columns: </span></span>
<span class="line"><span>        minmax(7em, 12em) </span></span>
<span class="line"><span>        repeat(3, max-content)</span></span>
<span class="line"><span>        1fr;</span></span>
<span class="line"><span>    row-gap: 2rem;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>第一列列轨道设置尺寸是 <code>minmax(7em, 12em)</code> ，这样做是让卡片上缩略图的大小控制在 <code>7em ~ 12em</code> 之间。由于媒体导航项的内容大小我们并不知，因此这里使用 <code>max-content</code> 来控制，最后一列设置 <code>1fr</code> ，将可用空间都留给这个列：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/399b5dacf7b9465db3114c6ab268e098~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>每张卡片（<code>.card</code>）它跨越五列（<code>grid-column: 1 / -1</code> 或 <code>grid-column: 1 / span 5</code>），可以在 <code>.card</code> 的 <code>grid-template-columns</code> 设置 <code>subgrid</code> ，继承父网格（<code>.cards</code>）的列轨道尺寸。另外在子网格上使用 <code>grid-template-rows</code> 重新定义自己的行网格轨道尺寸：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: min-content max-content min-content;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    column-gap: 1em;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/455fdf53a2b9491184a716729db90793~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>创建好网格之后，卡片中的标题（<code>h3</code> ）、描述文本（<code>p</code>）、缩略图（<code>img</code>）和导航列表项（<code>span</code>）就可以根据子网格（<code>.card</code>）的网格线名称放置到指定位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>h3 {</span></span>
<span class="line"><span>    grid-column: 1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>p {</span></span>
<span class="line"><span>    grid-column: 2 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>img {</span></span>
<span class="line"><span>    grid-row: 2 / -1;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>另一个卡片组件是像下图这样的，在内联轴方向平铺：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/25268de6eed946a1a2fb2eae6832658e~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/abKmQWj" target="_blank" rel="noreferrer">https://codepen.io/airen/full/abKmQWj</a></p></blockquote><p>其实前面有一个示例类似这种卡片组件的布局。只不过这个示例，我改了一下，让其变得稍微复杂那么一点。上面布局所需的 HTML 结构如下：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;cards&quot;&gt;&lt;!-- grid --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;&lt;!-- subgrid --&gt;</span></span>
<span class="line"><span>        &lt;div class=&quot;media&quot;&gt;&lt;!-- subgrid --&gt;</span></span>
<span class="line"><span>            &lt;img src=&quot;avatar.jpg&quot; alt=&quot;media object&quot; /&gt;</span></span>
<span class="line"><span>            &lt;p&gt;Media Content&lt;/p&gt;</span></span>
<span class="line"><span>        &lt;/div&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;Card Title&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;img src=&quot;card--figure.jpg&quot; alt=&quot;card figure&quot; /&gt;</span></span>
<span class="line"><span>        &lt;p&gt;Card Describe&lt;/p&gt;</span></span>
<span class="line"><span>        &lt;svg&gt;Like Icon&lt;/svg&gt;</span></span>
<span class="line"><span>        &lt;button&gt;More Button&lt;/button&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;!-- 省略的 card --&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>在最外层的卡片容器（<code>.cards</code>）上使用了 RAM 布局技术，让卡片在卡片容器中能能够根据空间自动断行，并且根据卡片组件的需要，使用 <code>grid-template-rows</code> 定义行网格轨道尺寸和数量：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.cards {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns: repeat(auto-fit, minmax(min(100% - 2rem, 18rem), 1fr));</span></span>
<span class="line"><span>    grid-template-rows: min-content min-content minmax(10rem, 14rem) auto auto;</span></span>
<span class="line"><span>    gap: 4rem;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a36815091a0c40d29f0445c5691c9167~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>每张卡片 <code>.card</code> 是父网格（<code>.cards</code>）的一个子网格，跨越父网格五行，并且继承父网格行网格轨道，不同的是重新定义了网格列轨道数量和尺寸，同时为了让卡片中的每个元素更易于放置，使用 <code>grid-template-areas</code> 在子网格上显式定义了网格区域名称。并且显式设置<code>gap</code> 值为 <code>0</code> ，重置了子网格轨道之间的间距：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card {</span></span>
<span class="line"><span>  grid-row: span 5;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>  display: inherit;</span></span>
<span class="line"><span>  grid-template-columns: 1rem min-content 1fr min-content 1rem;</span></span>
<span class="line"><span>  grid-template-rows: subgrid;</span></span>
<span class="line"><span>  grid-template-areas:</span></span>
<span class="line"><span>    &quot;.       media    media    media .&quot;</span></span>
<span class="line"><span>    &quot;.       title    title    title .&quot;</span></span>
<span class="line"><span>    &quot;figure  figure   figure   figure    figure&quot;</span></span>
<span class="line"><span>    &quot;.       describe describe describe  .&quot;</span></span>
<span class="line"><span>    &quot;.       like     .        button    .&quot;;</span></span>
<span class="line"><span>  gap: 0;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2eda52a75ef34697aab07f7b4d814cdd~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>卡片中的每个网格项目就可以使用 <code>grid-area</code> 来指定位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.media {</span></span>
<span class="line"><span>    grid-area: media;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>h3 {</span></span>
<span class="line"><span>    grid-area: title;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card &gt; img {</span></span>
<span class="line"><span>    grid-area: figure;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card &gt; p {</span></span>
<span class="line"><span>    grid-area: describe;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card svg {</span></span>
<span class="line"><span>    grid-area: like;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card button {</span></span>
<span class="line"><span>    grid-area: button;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br></div></div><p>在这个示例中，网格 <code>.card</code> 既是网格 <code>.cards</code> 的子网格，又是网格 <code>.media</code> 的父网格。因为，在 <code>.media</code> （网格项目）上也使用 <code>display: inherit</code> 定义了一个网格，同时继承其父网格 <code>.card</code> 的列网格轨道：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.media {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-areas: &quot;des    des    avatar&quot;;</span></span>
<span class="line"><span>    align-items: center;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6dca94529b7344048ab48553992286e7~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>在<code>.media</code> 网格中的网格项目也可以使用 <code>grid-area</code> 放置到对应的网格区域中，因为我们在 <code>.media</code> 中使用 <code>grid-template-areas</code> 创建了网格区域：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.media p {</span></span>
<span class="line"><span>  grid-area: des;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.media img {</span></span>
<span class="line"><span>  grid-area: avatar;</span></span>
<span class="line"><span>  justify-self: end;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>使用子网格<code>subgrid</code> 来构建卡片组件时，不管哪个网格项目的内容增加还是减少，卡片中的每个区域都可以对齐，让你的卡片组件整体视觉是好看的！</p><p>事实上，这种布局技术还可以用于 Web 上其他地方，比如页脚的导航、下拉菜单等：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3bb29df201de4ceb810755e19abc4d20~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>就拿页脚导航为例吧。构建这样的布局，你可能需要一个像下面这样的 HTML 结构：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;body&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;wrapper&quot;&gt;</span></span>
<span class="line"><span>        &lt;footer class=&quot;menu&quot;&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;menu__item&quot;&gt;</span></span>
<span class="line"><span>                &lt;h3 class=&quot;menu__heading&quot;&gt;Title&lt;/h3&gt;</span></span>
<span class="line"><span>                &lt;ul class=&quot;menu__lists&quot;&gt;</span></span>
<span class="line"><span>                    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Item&lt;/li&gt;</span></span>
<span class="line"><span>                &lt;/ul&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;!-- 省略其他 menu__item --&gt;</span></span>
<span class="line"><span>        &lt;/footer&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/body&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>我们要的是这样的一个效果：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/913208cb97e74c3189b7e8dadfe8a31b~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><ul><li>列数能够根据视窗大小自动调整，即自动断行；</li><li>导航菜单中，同一行中的区域，其标题与标题对齐，菜单项与菜单项对齐。</li></ul><p>实现第一个要求，在 CSS 网格布局中很简单，只需要使用 RAM 布局技术即可。但没有子网格（<code>subgrid</code>）的话，第二个要求实现起来就比较难，你得到的效果将会像下图这样：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/45866cc5f95f4bf99064eb96fbe667ba~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>你可以像上面卡片示例一样，将 <code>.menu</code> 和 <code>.menu__item</code> 都定义为网格，而且 <code>.meun__item</code> 网格是 <code>.menu</code> 网格的子网格，在子网格 <code>.menu__item</code> 跨越两行，并且设置它的 <code>grid-template-rows</code> 值为 <code>subgrid</code> 。这样做是让子网格继承父网格的行网格轨道，当子网格行网格轨道尺寸变大时，它的父网格行网格轨道也会变大。你就可以实现第二个要求。</p><p>整个页脚导航的布局效果，除了运用了 CSS 子网格、RAM 布局技术之外，还使用了 Full-Bleed 布局技术，有关于布局的详细代码如下所示：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>/* Full-Bleed 布局技术 */</span></span>
<span class="line"><span>body {</span></span>
<span class="line"><span>    --limit-max-container-width: 1024px;</span></span>
<span class="line"><span>    --limit-min-container-width: 320px;</span></span>
<span class="line"><span>    --gutter: 1rem;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns:</span></span>
<span class="line"><span>        minmax(var(--gutter), 1fr)</span></span>
<span class="line"><span>        minmax(</span></span>
<span class="line"><span>            min(var(--limit-min-container-width), 100% - var(--gutter) * 2),</span></span>
<span class="line"><span>            var(--limit-max-container-width)</span></span>
<span class="line"><span>        )</span></span>
<span class="line"><span>        minmax(var(--gutter), 1fr);</span></span>
<span class="line"><span>    row-gap: var(--gutter);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.wrapper {</span></span>
<span class="line"><span>    /* 从第一列跨越到最后一列*/</span></span>
<span class="line"><span>    grid-column: 1 / -1;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>  </span></span>
<span class="line"><span>    /* 继承父网格 body 的网格特性*/</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>footer {</span></span>
<span class="line"><span>    /* 将 footer 放置在中间列 */</span></span>
<span class="line"><span>    grid-column: 2 / 3;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 使用 RAM 布局技术，实现网格项目的自动断行 */</span></span>
<span class="line"><span>    grid-template-columns: repeat(auto-fit, minmax(min(100% - 2rem, 20rem), 1fr));</span></span>
<span class="line"><span>    gap: 2rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.menu__item {</span></span>
<span class="line"><span>    /* 每个网格项目跨越两行，标题一行，菜单项一行 */</span></span>
<span class="line"><span>    grid-row: span 2;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 继承父网格 footer 的网格特性 */</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>    row-gap: 1rem;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br></div></div><p>不难发现，示例中的 <code>body</code> 、<code>.wrapper</code> 、<code>footer</code> 和 <code>.menu__item</code> 都是网格，它们之间的关系是：</p><ul><li><code>.wrapper</code> 网格是 <code>body</code> 网格的子网格，并且在 <code>.wrapper</code> 上设置了 <code>grid-template-columns</code> 值为 <code>subgrid</code> ，<code>.wrapper</code> 网格将继承父网格 <code>body</code> 的列网格轨道数量和尺寸。</li><li><code>footer</code> 网格嵌套在 <code>.wrapper</code> 网格内，但并没有在 <code>grid-template-columns</code> 或 <code>grid-template-rows</code> 属性上显式设置值为 <code>subgrid</code> ，因此它们只是嵌套关系，<code>footer</code> 和 <code>.wrapper</code> 是两个独立的网格。</li><li><code>.menu__item</code> 网格是 <code>footer</code> 网格的子网格， <code>.menu__item</code> 项目跨越两行，同时将其 <code>grid-template-rows</code> 属性设置为 <code>subgrid</code> ，因此它将继承其父网格 <code>footer</code> 的行网格轨道特性。页脚菜单每一栏的标题相互对齐，菜单项相互对齐。</li></ul><p>你最终看到的效果如下：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/659526f8e7d64e459e50dbaf562aad28~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/poKNLbE" target="_blank" rel="noreferrer">https://codepen.io/airen/full/poKNLbE</a></p></blockquote><p>感兴趣的同学，可以使用同样的技术（RAM 布局技术和子网格布局）来实现下图中下拉导航的布局：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f0d4330200d84a579a2b8ae9d34fba7f~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><h2 id="品牌页-区-布局" tabindex="-1">品牌页（区）布局 <a class="header-anchor" href="#品牌页-区-布局" aria-label="Permalink to &quot;品牌页（区）布局&quot;">​</a></h2><p>在 Web 页面的设计中，常常会有通栏的横幅的设计效果，往往把这种效果称为 <strong>Branding</strong> 。如下图所示：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fcb8b31b500a4760ac2e15ff0fa1e7b1~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>它包含了三个部分：</p><ul><li>标题（Headline）；</li><li>特色功能区（Featured Section）；</li><li>普通卡片区（Card）。</li></ul><p>它的 HTML 结构可以像下面这样：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;section class=&quot;branding&quot;&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;headline&quot;&gt;&lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;featured&quot;&gt;&lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;&lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>当然，你可以根据自己需要往相应的区域继续填充内容，比如：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;section class=&quot;branding&quot;&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;headline&quot;&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;主标题&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;h4&gt;次标题&lt;/h4&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;featured&quot;&gt;</span></span>
<span class="line"><span>        &lt;div class=&quot;featured__content&quot;&gt;&lt;!-- 内容区域 --&gt;</span></span>
<span class="line"><span>            &lt;h3&gt;特色功能区域:标题&lt;/h3&gt;</span></span>
<span class="line"><span>            &lt;blockquote&gt;特色功能区域：描述文本&lt;/blockquote&gt;</span></span>
<span class="line"><span>        &lt;/div&gt;</span></span>
<span class="line"><span>        &lt;figure class=&quot;featured__thumbnail&quot;&gt;</span></span>
<span class="line"><span>            &lt;img src=&quot;featured--thumbnail.jpg&quot; alt=&quot;特色功能区域缩略图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;/figure&gt;    </span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;</span></span>
<span class="line"><span>        &lt;figure&gt;</span></span>
<span class="line"><span>            &lt;img src=&quot;card--thumbnail.jpg&quot; alt=&quot;卡片缩略图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;/figure&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;卡片标题&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;p&gt;卡片描述文本&lt;/p&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/section&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><p>假设设计师将整个 Branding 区域<strong>均分为五列</strong> ，除了“特色功能区域（Featured Section）” 占了三列之外，其他两个区域（Headline 和 Card）只各占一列，如下图所示：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/efe64e47f4264ef4b9739f66871ea895~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>使用网格布局很容易就将它均分成五份，使用网格线可以将它们放置到指定的区域：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.branding {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-columns: repeat(5, minmax(0, 1fr));</span></span>
<span class="line"><span>    gap: 1rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured {</span></span>
<span class="line"><span>    grid-column: 2 / span 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card {</span></span>
<span class="line"><span>    grid-column: 5;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p><code>.featured</code> 网格项目（即 “特色功能区域” ）的 <code>grid-column</code> 属性设置了 <code>2 / span 3</code> 值，表示它将放置在列网格线<code>2</code> （起始位置），并且向右合并三列（<code>span 3</code>），相当于 <code>grid-column: 2 / 5</code> ，即从第二列起始网格线跨越到第五列起始网格线。</p><p>为了让 <code>.featured</code> 网格项目能继承父网格（<code>.branding</code>）的网格特性，得到更好的控制，需将其设置为一个子网格（<code>display</code> 设置为 <code>inherit</code> 或 <code>grid</code> ），并且将其 <code>grid-tempalte-columns</code> 设置为 <code>subgrid</code> ：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.featured {</span></span>
<span class="line"><span>    grid-column: 2 / span 3;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>为了能更好地放置该网格中的网格项目（“特色功能区域”中的内容<code>.featured__content</code> 和缩略图 <code>.featured__thumbnail</code>），你还可以显式设置 <code>grid-template-areas</code> 属性的值：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.featured {</span></span>
<span class="line"><span>    grid-column: 2 / span 3;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-areas: &quot;content thumbnail thumbnail&quot;;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>内容区域占一列，缩略图占两列：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0d1ce51ed1454125b86244b0c0a5b36c~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.featured__content {</span></span>
<span class="line"><span>    grid-area: content;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__thumbnail {</span></span>
<span class="line"><span>    grid-area: thumbnail;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/oNyzOYj" target="_blank" rel="noreferrer">https://codepen.io/airen/full/oNyzOYj</a></p></blockquote><p>这样做，“特色功能区”中的主内容列和缩略图列，能与其父网格（<code>.branding</code>）所对应的列完全匹配，列轨道大小、列间距等。这一切都要归功于子网格（<code>subgrid</code>）的功能。</p><p>在这个基础上，你还可以稍微加点内容，改变一下结构，就可以构建出一个 Landing Page 页的布局效果：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ac78cb4075084d77bbb940fcd8dee964~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/abKBLGJ" target="_blank" rel="noreferrer">https://codepen.io/airen/full/abKBLGJ</a></p></blockquote><p>在前一个示例的“特色功能区域”下面新增一个“标题”、“列表”和“按钮”，你可以考虑用一个 <code>&lt;div&gt;</code> 来包裹它们：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;landing&quot;&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;headline&quot;&gt;...&lt;/div&gt;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    &lt;!-- 使用一个 div 将特色功能区域、新增的标题、列表和按钮包裹起来 --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;featured--section&quot;&gt;</span></span>
<span class="line"><span>        &lt;div class=&quot;featured&quot;&gt;&lt;!-- 特色功色区域结构不变 --&gt;&lt;/div&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;新增标题&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;ul&gt;&lt;!-- 新增列表 --&gt;</span></span>
<span class="line"><span>            &lt;li&gt;</span></span>
<span class="line"><span>                &lt;span&gt;01&lt;/span&gt;</span></span>
<span class="line"><span>                &lt;p&gt;列表内容&lt;/p&gt;</span></span>
<span class="line"><span>            &lt;/li&gt;</span></span>
<span class="line"><span>            &lt;!-- 此处省略两个一样的 li --&gt;    </span></span>
<span class="line"><span>        &lt;/ul&gt;</span></span>
<span class="line"><span>        &lt;button&gt;新增按钮&lt;/button&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;...&lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>在前面的基础上稍微调整了一下网格的定义：</p><ul><li>在 <code>.landing</code> 上定义了一个四行五列（<code>4 x 5</code>）的网格，这是最外层的主网格，和前面示例相比，这里显式定义网格的行网格轨道的数量和尺寸。</li><li>将新增的 <code>.featured--section</code> 容器合并三列四行，同时将 <code>grid-template-rows</code> 和 <code>grid-template-columns</code> 定义为 <code>subgrid</code> ，让该子网格继承其父网格 <code>.landing</code> 的网格特性。</li><li>在 <code>.featured--section</code> 的 <code>.featured</code> 和 <code>ul</code> （列表）也是一个子网格，它们都跨越三列，继承父网格 <code>.featured--section</code> 网格轨道。</li></ul><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/772204318c0a42b4a9713087480ba30e~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.landing {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 主（父）网格，创建一个四行五列的网格 */</span></span>
<span class="line"><span>    grid-template-columns: repeat(5, minmax(0, 1fr));</span></span>
<span class="line"><span>    grid-template-rows: repeat(4, auto);</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    gap: 1rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>/* 子网格 */</span></span>
<span class="line"><span>.featured--section {</span></span>
<span class="line"><span>    /* 合并三列四行 */</span></span>
<span class="line"><span>    grid-column: 2 / span 3;</span></span>
<span class="line"><span>    grid-row: 1 / span 4;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 继承父网格 .landing 的网格轨道数量和尺寸 */</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 重置子网格的行网格轨道之间间距，子网格的列网格之间间距继承父网格的列网格轨道的间距 */</span></span>
<span class="line"><span>    row-gap: 1rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured {</span></span>
<span class="line"><span>    grid-column: 1 / span 3;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 继承父网格 .featured--section 的列网格轨道 */</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 显式给子网格命名网格区域名称 */</span></span>
<span class="line"><span>    grid-template-areas: &quot;content thumbnail thumbnail&quot;;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__content {</span></span>
<span class="line"><span>    grid-area: content;</span></span>
<span class="line"><span>    align-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__thumbnail {</span></span>
<span class="line"><span>    grid-area: thumbnail;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured--section &gt; h3 {</span></span>
<span class="line"><span>    grid-column: 1 / span 3;</span></span>
<span class="line"><span>    grid-row: 2;</span></span>
<span class="line"><span>    place-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span></span></span>
<span class="line"><span>ul {</span></span>
<span class="line"><span>    grid-column: 1 / span 3;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>     </span></span>
<span class="line"><span>     /* 继承父网格 .featured--section 的列网格轨道  */</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>ul li {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 创建嵌套网格，不会继承父网格任何特性，是一个独立的网格 */</span></span>
<span class="line"><span>    grid-template-columns: 1fr 2fr 1fr;</span></span>
<span class="line"><span>    grid-template-rows: 2rem 1fr 2rem;</span></span>
<span class="line"><span>    gap: 10px;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>ul span {</span></span>
<span class="line"><span>    grid-area: 1 / 2 / 4 / 3;</span></span>
<span class="line"><span>    place-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>ul p {</span></span>
<span class="line"><span>    grid-area: 2 / 2 / 3 / 4;</span></span>
<span class="line"><span>    z-index: 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>button {</span></span>
<span class="line"><span>  grid-column: 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card {</span></span>
<span class="line"><span>  grid-column: 5;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br></div></div><p>注意，示例中列表项的布局效果是一种<strong>交叉叠加</strong>的布局，这里采用了嵌套网格来实现，如果你感兴趣的话，可以尝试使用子网格来实现。</p><p>在“特色功能区域”中还可以与 CSS 的多列布局结合在一起，构建类似一个简单的报刊类的布局：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7144d19abba44e079f220f0b33d466d8~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/GRGNyVO" target="_blank" rel="noreferrer">https://codepen.io/airen/full/GRGNyVO</a></p></blockquote><p>实现上图布局效果，HTML 结构调整并不大：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;section class=&quot;branding&quot;&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;headline&quot;&gt;...&lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;featured&quot;&gt;</span></span>
<span class="line"><span>        &lt;h3 class=&quot;featured__title&quot;&gt;特色功能区域:标题&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;figure class=&quot;featured__thumbnail&quot;&gt;</span></span>
<span class="line"><span>            &lt;img src=&quot;featured--thumbnail.jpg&quot; alt=&quot;特色功能区域缩略图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;/figure&gt;    </span></span>
<span class="line"><span>        &lt;div class=&quot;featured__content&quot;&gt;&lt;!-- 内容区域 --&gt;</span></span>
<span class="line"><span>           &lt;blockquote&gt;特色功能区域：描述文本&lt;/blockquote&gt;</span></span>
<span class="line"><span>        &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card&quot;&gt;...&lt;/div&gt;</span></span>
<span class="line"><span>&lt;/section&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p>只是把 <code>.featured</code> 网格区域的名称和结构做了一下调整：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.featured {</span></span>
<span class="line"><span>    grid-column: 2 / span 3;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-areas: </span></span>
<span class="line"><span>       &quot;title   thumbnail thumbnail&quot;</span></span>
<span class="line"><span>       &quot;content content   content&quot;;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__content {</span></span>
<span class="line"><span>    grid-area: content;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__thumbnail {</span></span>
<span class="line"><span>    grid-area: thumbnail;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.featured__title {</span></span>
<span class="line"><span>    grid-area: title;</span></span>
<span class="line"><span>    place-self: center;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ad4801c8b6324cf882d4dca6ad05fc24~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>示例中，在内容区域<code>.featured__content</code> 使用 CSS 多列布局中的 <code>column-count</code> 、<code>column-gap</code> 和 <code>column-rule</code> 将其分成三列布局：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.featured__content {</span></span>
<span class="line"><span>    column-count: 3;                   /* 设置列数 */</span></span>
<span class="line"><span>    column-gap: 1rem;                  /* 设置列间距 */</span></span>
<span class="line"><span>    column-rule: 1px dashed aliceblue; /* 设置列之间分隔线 */</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h2 id="图片墙" tabindex="-1">图片墙 <a class="header-anchor" href="#图片墙" aria-label="Permalink to &quot;图片墙&quot;">​</a></h2><p>子网格用来构建图片墙也是很有用的，比如下图这样的布局，左侧有一个内容区域，它包含了一个标题和一段描述文本，右侧是九宫的图片展示区：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ad67a745e17f409090f010d0f9631f54~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>上图仅是图片墙的一种排列网格，其实右侧你可以根据自己的需要，设计出不同的九宫格网格，甚至是比九宫格风格复杂繁多的宫格，比如下图这些延伸的风格：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d6b9538a3e5b43cc9e3a50d6c39e67f6~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>当然，你可能会说，不使用子网格也可以构建出所期望的图片墙的布局效果。的确如此，不使用子网格，你需要创建一个复杂的网格。如果使用子网格，你更多的关注点是在右图宫格的布局上，而这种九宫格的布局风格，CSS 网格是有天然优势的。</p><p>构建上面展示的图片墙布局效果，所需要的 HTML 结构如下所示：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;gallery&quot;&gt;&lt;!-- 父网格 --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;gallery__content&quot;&gt;</span></span>
<span class="line"><span>        &lt;h3&gt;Gallery Title&lt;/h3&gt;</span></span>
<span class="line"><span>        &lt;p&gt;Gallery Describe&lt;/p&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;gallery__photo&quot;&gt;&lt;!-- 子网格 --&gt;</span></span>
<span class="line"><span>        &lt;img src=&quot;gallery-photo.jpg&quot; alt=&quot;图片&quot; /&gt;</span></span>
<span class="line"><span>        &lt;!-- 省略其他的 img --&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>设计师将整个图片墙组件分成六列，内图和图片各占三列。右侧的图片展示区是一个三列 <code>N</code> 行的网格（行数<code>N</code> 会随图片增加而自动增加，即创建隐式的行网格轨道）。在这个示例中，将右侧图片展示区<code>.gallery__photo</code> 定义为 <code>.gallery</code> 网格的子网格，并且继承父网格的列网格轨道特性。</p><p>有关于布局的 CSS 代码如下所示：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.gallery {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    gap: 2rem;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-template-columns: repeat(6, minmax(0, 1fr));</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__content {</span></span>
<span class="line"><span>    grid-column: 1 / span 3;</span></span>
<span class="line"><span>    place-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo {</span></span>
<span class="line"><span>    grid-column: 4 / span 3;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: minmax(auto, 180px);</span></span>
<span class="line"><span>    row-gap: 1rem;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    grid-auto-flow: dense;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo img:nth-child(1) {</span></span>
<span class="line"><span>    grid-row: 1;</span></span>
<span class="line"><span>    grid-column: 1 / span 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo img:nth-child(2) {</span></span>
<span class="line"><span>    grid-row: 2;</span></span>
<span class="line"><span>    grid-column: 1 / 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo img:nth-child(3) {</span></span>
<span class="line"><span>    grid-row: 2;</span></span>
<span class="line"><span>    grid-column: 2 / 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo img:nth-child(4) {</span></span>
<span class="line"><span>    grid-row: 1 / span 2;</span></span>
<span class="line"><span>    grid-column: 3 / 4;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.gallery__photo img:nth-child(5) {</span></span>
<span class="line"><span>    grid-row: 3 / 4;</span></span>
<span class="line"><span>    grid-column: 1 / span 3;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fda3f46191f84215b81b3223b6b07d8e~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/eYKggqV" target="_blank" rel="noreferrer">https://codepen.io/airen/full/eYKggqV</a></p></blockquote><p>你可以尝试着将右侧九宫格替换成你自己希望要的风格。</p><h2 id="交叉叠加布局" tabindex="-1">交叉叠加布局 <a class="header-anchor" href="#交叉叠加布局" aria-label="Permalink to &quot;交叉叠加布局&quot;">​</a></h2><p>不知道你平时浏览 Web 页面或 Web 设计，有没有留意到，Web 页面元素相互交叉叠加的布局效果越来越频繁，比如：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/89c2da1b3ec142b4823ee41d57b339b5~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>在还没有 CSS 网格布局技术之前，Web 开发者一般都是采用绝对定位来构建。虽然绝对定位可以实现上图中交叉叠加的布局效果，但缺乏灵活性和适配性，无法较好地适配更多的终端设备。不过，使用 CSS 网格布局，尤其是结合子网格特性，就显得要容易得多，而且适配性、灵活性都要比绝对定位强很多。</p><p>我们一起来看一个很有创意性的示例，这个示例是 <a href="https://codepen.io/michellebarker/full/JjGNdNY" target="_blank" rel="noreferrer">@Michelle Barker 在 Codepen 上写的</a>，我觉得很有创意，就拿来和大家一起探讨。示例的效果如下：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9cc1ca79ec2647ee8dac6fc5fb7a4b4a~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/poKRPxz" target="_blank" rel="noreferrer">https://codepen.io/airen/full/poKRPxz</a> 注意，上图这个效果是在 <a href="https://codepen.io/michellebarker/full/JjGNdNY" target="_blank" rel="noreferrer">@Michelle Barker </a>提供的案例上做了改良的 ！</p></blockquote><p>基于卡片的 UI 是 Web 页同上常见的一种设计模式，但构建一个需要悬浮（<code>:hover</code>）或获得焦点（<code>:focus</code>）效果应用于整个卡片的 UI 并不常见。像上图这种交互效果，很多 Web 开发者往往会采用一种粗暴的策略，即在整个卡片的悬浮或获得焦点状态时，改变相应元素的 UI 效果：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card:hover img,</span></span>
<span class="line"><span>.card:focus img {</span></span>
<span class="line"><span>    /* 卡片悬浮或获得焦点状态下改变 img 样式*/</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card:hover .card__content,</span></span>
<span class="line"><span>.card:focus .card__content {</span></span>
<span class="line"><span>    /* 卡片悬浮或获得焦点状态下改变 卡片内容样式 */</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>这种策略有一个显著的缺点，鼠标只要悬浮到卡片上（或只要卡片获得焦点），相应的图片和卡片内容样式就会发生改变。这种策略实现的效果是不符合 Web 设计师预期的。</p><p>因为 Web 设计预期的效果是 “鼠标悬浮到图片或卡片内容时，才改变相应的样式”（如上图所示）。为了达到这样的交互效果，我们添加了一个空的链接标签<code>&lt;a&gt;</code> ，并且使用其伪元素 <code>::before</code> 和 <code>::after</code>来生成一个空白区域，分别遮盖在卡片的图片和内容区域上面：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/22a63f3a5d794cce86743b4fa9fc4739~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.link:hover ~ img,</span></span>
<span class="line"><span>.link:focus ~ img {</span></span>
<span class="line"><span>     /* 链接悬浮或获得焦点状态下改变图片样式 */</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>.link:hover ~ .grid__card,</span></span>
<span class="line"><span>.link:focus ~ .grid__card {</span></span>
<span class="line"><span>    /* 链接悬浮或获得焦点状态下改变卡片内容样式 */</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>类似下图这样的一个效果就实现了：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e991d1fbc883462da7e33a78fdda8065~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/shadeed/full/jOOwwpY/66e9c2039b50463d96a2a9832f05ec0f" target="_blank" rel="noreferrer">https://codepen.io/shadeed/full/jOOwwpY/66e9c2039b50463d96a2a9832f05ec0f</a></p></blockquote><p>伪元素实现该交互效果的详细介绍并不是我们这个课程要介绍的重点，如果你对这种技术感兴趣，可以移步阅读 @Ahmad Shadeed的《<a href="https://ishadeed.com/article/unusual-use-cases-pseudo-elements/" target="_blank" rel="noreferrer">Uncommon Use Cases For Pseudo Elements</a>》，或早前我整理的一篇关于 CSS 伪元素的教程《<a href="https://www.w3cplus.com/css/use-case-pseudo-elements.html" target="_blank" rel="noreferrer">伪元素能帮我们做些什么？</a>》。</p><p>如今我们知道实现这种交互效果的技术方案了，但还需要一个更灵活的布局。以往一般采用的是绝对定位，将伪元素分别定位到图片和内容区域的上面。刚才提到过了，它是有缺陷的，很多时候我们并不知道输出的图片、内容区域大小。</p><p>庆幸的是，使用 CSS 网格布局，这一切就显得那么简单。你实现这个卡片，可能会需要一个像下面这样的 HTML 结构：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;grid&quot;&gt;</span></span>
<span class="line"><span>    &lt;!-- 这个空链接标签很重要，实现交互效果我们需要用到它的伪元素，另外该标签一定要放在图片和卡片内容标签前面 --&gt;</span></span>
<span class="line"><span>    &lt;a href=&quot;&quot; class=&quot;link&quot;&gt;&lt;/a&gt;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    &lt;!-- 卡片上的缩略图 --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;grid__img&quot;&gt;</span></span>
<span class="line"><span>        &lt;img src=&#39;https://picsum.photos/800?random=5&#39; alt=&#39;卡片图片&#39;&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    &lt;!-- 卡片上的内容 --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;grid__card&quot;&gt;</span></span>
<span class="line"><span>        &lt;h2&gt;卡片标题&lt;/h2&gt;</span></span>
<span class="line"><span>        &lt;p&gt;卡片描述文本&lt;/p&gt;</span></span>
<span class="line"><span>        </span></span>
<span class="line"><span>        &lt;!-- 这是链接提示文案 --&gt;</span></span>
<span class="line"><span>        &lt;span class=&quot;fake-link&quot;&gt;阅读更多&lt;span&gt;→&lt;/span&gt;&lt;/span&gt;</span></span>
<span class="line"><span>  &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>上面结构看上去很简单，但其中有一个细节尤其重要。添加了一个空的链接标签<code>&lt;a&gt;</code> ，它的位置必须放置在卡片图片 <code>.grid__img</code> 和 卡片内容 <code>.grid__card</code> 的前面。我们将使用 CSS 的相邻选择器（<code>E ~ F</code>）来选中它们：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.link:hover ~ .grid__img,</span></span>
<span class="line"><span>.link:focus ~ .grid__img {</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.link:hover ~ .grid__card,</span></span>
<span class="line"><span>.link:focus ~ .grid__card {</span></span>
<span class="line"><span></span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>简单地分析一下布局的策略。</p><ul><li>将卡片容器 <code>.grid</code> 定义为一个三行三列的网格，将它的 <code>grid-template-columns</code> 和 <code>grid-tempate-rows</code> 属性的值都设置为 <code>repeat(3, minmax(0, 1fr))</code>。</li><li>使用 <code>grid-area</code> 属性，根据网格线名称，将图片 <code>.grid__img</code> 和 <code>.grid__card</code> 放置到相应的位置，比如图片放在卡片左上角，卡片内容放置在卡片右下角，两者在卡片正中间相互交叉与叠加。</li></ul><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>body {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>  </span></span>
<span class="line"><span>    /* RAM 布局技术，实现卡片自动断行*/</span></span>
<span class="line"><span>    grid-template-columns: repeat(auto-fit, minmax(min(100% - 3rem, 30rem), 1fr));</span></span>
<span class="line"><span>    gap: 2rem;</span></span>
<span class="line"><span>    align-content: start;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.grid {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 创建一个三行三列的网格 */</span></span>
<span class="line"><span>    grid-template-columns: repeat(3, minmax(0, 1fr));</span></span>
<span class="line"><span>    grid-template-rows: repeat(3, minmax(0, 1fr));</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>/* 将卡片上的缩略图放置到指定的位置 */</span></span>
<span class="line"><span>.grid__img {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / 3 / 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>/* 单双数卡片上缩略图位置刚好相反 */</span></span>
<span class="line"><span>.grid:nth-child(2n) .grid__img {</span></span>
<span class="line"><span>    grid-area: 2 / 2 / 4 / 4;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>/* 将卡片上的内容放置到指定的位置 */</span></span>
<span class="line"><span>.grid__card {</span></span>
<span class="line"><span>    grid-area: 2 / 2 / 4 / 4;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>/* 单双数卡片上的内容位置刚好相反 */</span></span>
<span class="line"><span>.grid:nth-child(2n) .grid__card {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / 3 / 3;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/16edb28bda4c42ec83f9fe10af4b1ba7~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>我们需要将 <code>a.link</code> 的伪元素 <code>::before</code> 和 <code>::after</code> 分别遮盖在卡片的图片<code>.grid__img</code> 和 <code>.grid__card</code> 上面，为了位置和大小能和它们完全相匹配，采用子网格是较好的一种策略。我们需要做的是：</p><ul><li><code>.link</code> 要和父网格一样的大，简单地说，合并三行三列，使用 <code>grid-area</code> 就可以轻易地实现，因为它也是父网格 <code>.grid</code> 的一个网格项目。</li><li>将 <code>.link</code> 也定义为一个网格，并且将它的 <code>grid-template-columns</code> 和 <code>grid-templage-rows</code> 都设置为 <code>subgrid</code> ，这样就完全继承父网格 <code>.grid</code> 的特性。</li><li>像放置卡片上的缩略图和内容一样，使用 <code>grid-area</code> 将链接<code>.link</code> 的伪元素 <code>.link::before</code> 、<code>.link::after</code> 放置到指定位置，它们的位置和卡片上缩略图和内容区域是相同的：</li></ul><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.link {</span></span>
<span class="line"><span>  grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>  display: inherit;</span></span>
<span class="line"><span>  grid-template-columns: subgrid;</span></span>
<span class="line"><span>  grid-template-rows: subgrid;</span></span>
<span class="line"><span>  z-index: 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.link::before {</span></span>
<span class="line"><span>  grid-area: 1 / 1 / 3 / 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>.link::after {</span></span>
<span class="line"><span>  grid-area: 2 / 2 / 4 / 4;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span></span></span>
<span class="line"><span>.grid:nth-child(2n) .link::before {</span></span>
<span class="line"><span>  grid-area: 1 / 1 / 3 / 3;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.grid:nth-child(2n) .link::after {</span></span>
<span class="line"><span>  grid-area: 2 / 2 / 4 / 4;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8a4a7a5fed434adcb214806ef1dfd7c9~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>由于卡片上的缩略图（<code>.grid__img</code>）、内容区域（<code>.grid__card</code>）、链接伪元素（<code>.link::before</code> 和 <code>.link::after</code>）会有一定区域的交叉和层叠：</p><ul><li>内容区域（<code>.grid__card</code>）和缩略图（<code>.grid__img</code>）有一定交叉区域（网格线 <code>2 / 2 / 3 / 3</code> 围绕的区域），并且在 <code>z</code> 轴上，内容区域是高于缩略图的，因此要显式设置 <code>z-index</code> 的话，<code>.grid__card</code> 的 <code>z-index</code> 要大于 <code>.grid__img</code> 的。</li><li>链接伪元素 <code>.link::before</code> 和 <code>.link::after</code> 同样在网格线 <code>2 / 2 / 3 / 3</code> 围绕的区域相互交叉，并且在 <code>z</code> 轴上 <code>.link::after</code> 高于 <code>.link::before</code> 。</li><li>链接伪元素 <code>.link::before</code> 和 <code>.link::after</code> 分别与卡片缩略图 <code>.grid__img</code> 和内容区域 <code>.grid__card</code> 相互重叠。在该示例中，为了保证交互效果不出问题，需要确保 <code>.link::before</code> 和 <code>.link::after</code> 在 <code>z</code> 轴上高于 <code>.grid__img</code> 和 <code>.grid__card</code>。</li></ul><p>在这个示例中，默认情况下（即，各个元素上未显式设置 <code>z-index</code> 值），<code>.link</code> 在 <code>z</code> 轴上层级低于 <code>.grid__img</code> 和 <code>.grid__card</code> ，这也造成 <code>.link::before</code> 和 <code>.link::after</code> 两个伪元素在 <code>z</code> 轴上也低于 <code>.grid__img</code> 和 <code>.grid__card</code> 。</p><p>而 <code>.grid__card</code> 在 <code>z</code> 轴上的层级是高于 <code>.grid__img</code> 。这是因为，在 CSS 中如果网格项目未显式设置 <code>z-index</code> 的值，它将按照元素在 HTML 文档源码中出现的顺序为参照值，越在后面出现，在 <code>z</code> 轴的层级越高。</p><p>为了避免卡片内容被缩略图遮盖，同时为了保证卡片上交互正常，我们可以给 <code>.link</code> 和 <code>.grid__content</code> 的 <code>z-index</code> 属性设置一个值：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.link {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    z-index: 3; /* 确保该值大于 .grid__card 值*/</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.grid__card {</span></span>
<span class="line"><span>    grid-area: 2 / 2 / 4 / 4;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    z-index: 2;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>再来看一个运用 <code>subgrid</code> 布局的卡片组件：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f5a8cfff72c34bdcbbd664a69de0476d~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>看上去很普通的一个卡片组件，但它有一个很显著的特征，图片的标注和卡片标题是对齐，并且主内容与图片之间有一定的空白间距：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/91ea82684caa4552a2a4cec900cc0d24~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>你可能会说，CSS 实现上图这样的布局效果已经是非常容易的了。这样说并不错，但是在一定的结构限制之下，比如说，为了让 Web 可访问性做得更好一些，对屏幕阅读器更友好一些，构建上图的 HTML 结构可能会是下面这样：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;card&quot;&gt;</span></span>
<span class="line"><span>    &lt;figure&gt;</span></span>
<span class="line"><span>        &lt;img src=&quot;thumb.jpg&quot; alt=&quot;卡片缩略图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;figcaption&gt;图片标注&lt;/figcaption&gt;</span></span>
<span class="line"><span>    &lt;/figure&gt;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    &lt;h3 class=&quot;title&quot;&gt;卡片标题&lt;/h3&gt;</span></span>
<span class="line"><span>    &lt;p&gt;卡片描述&lt;/p&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>试想一下，不管你是准备使用 Flexbox 还是 Grid 来构建布局，要实现上图的效果是没有那么容易的。所以说，当 HTML 结构有一定的限制时，常用的 Web 布局技术要实现起来就显得没那么容易了。不过，使用 CSS 子网格来构建这种卡片布局，就容易很多了。</p><p>我们可以在卡片 <code>.card</code> 上像下面这样定义一个网格：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span> .card { </span></span>
<span class="line"><span>     display: grid; </span></span>
<span class="line"><span>     grid-template-columns: 1fr 1fr 50px 50px 1fr 1fr; </span></span>
<span class="line"><span>     grid-template-rows: repeat(3, min-content); </span></span>
<span class="line"><span>     gap: 1rem 1.25rem; </span></span>
<span class="line"><span> }</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0fd058b67da34458b33595b31e2b40b7~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>同时 <code>figure</code> 跨五列两行：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span> figure { </span></span>
<span class="line"><span>     grid-row: 2 / span 2; </span></span>
<span class="line"><span>     grid-column: 1 / span 5; </span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a9359f11102f48f79a3c9f3e934fc68c~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>此时，在 <code>figure</code> 上使用 <code>subgrid</code> ，并将 <code>img</code> 和 <code>figcaption</code> 按网格线放置到指定位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>figure { </span></span>
<span class="line"><span>    display: grid; </span></span>
<span class="line"><span>    grid-template-rows: subgrid; </span></span>
<span class="line"><span>    grid-template-columns: subgrid; </span></span>
<span class="line"><span>} </span></span>
<span class="line"><span></span></span>
<span class="line"><span>figure img { </span></span>
<span class="line"><span>    grid-column: 1 / span 3; </span></span>
<span class="line"><span>    grid-row: 1 / span 2; </span></span>
<span class="line"><span>} </span></span>
<span class="line"><span></span></span>
<span class="line"><span>figcaption { </span></span>
<span class="line"><span>    grid-row: 2; </span></span>
<span class="line"><span>    grid-column: 4 / span 2; </span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/853fe9fe141e49148d07375d531b2003~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>你最终看到的效果如下：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cde0a86c6863420cb972207dc1bb1459~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/YzvZKxV" target="_blank" rel="noreferrer">https://codepen.io/airen/full/YzvZKxV</a></p></blockquote><h2 id="百分百宽度的条纹布局" tabindex="-1">百分百宽度的条纹布局 <a class="header-anchor" href="#百分百宽度的条纹布局" aria-label="Permalink to &quot;百分百宽度的条纹布局&quot;">​</a></h2><p>百分百宽度的条纹布局其实是 <strong>Full-Bleed</strong> 布局效果的延伸，它看起来像下面这样：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6a229d20e4d943359897c304d489af44~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>上图这种布局效果也是 Web 布局中常见的一种，它有着自己的特色，比如有全屏的、距离左侧或右侧有一定空白空间的。</p><p>如果我们把整个布局分成三列，类似于 Full-Bleed 布局，左侧和右侧都是自适应的，主栏是固定宽度的。那么：</p><ul><li>全屏就是跨越网格三列；</li><li>距离左侧有一定空白空间就是跨越两列，而且是从主栏起始到右侧栏结束位置；</li><li>距离右侧有一定空白空间就是跨越两列，而且从左侧栏起始到主栏结束位置。</li></ul><p>使用 CSS 网格可以很容易实现 <strong>Full-Bleed</strong> 布局：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;container&quot;&gt;</span></span>
<span class="line"><span>  &lt;h1&gt;现代 Web 布局：使用 CSS 网格构建 Full-Bleed 布局&lt;/h1&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that a ...&lt;/p&gt;</span></span>
<span class="line"><span>  &lt;section class=&quot;full__bleed&quot;&gt;</span></span>
<span class="line"><span>    &lt;img src=&quot;https://picsum.photos/2568/600?random=1&quot; width=&quot;2568&quot; height=&quot;600&quot; alt=&quot;&quot; /&gt;</span></span>
<span class="line"><span>  &lt;/section&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that ...&lt;/p&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span>
<span class="line"><span>.container {</span></span>
<span class="line"><span>    --limit-max-container-width: 1024px;</span></span>
<span class="line"><span>    --limit-min-container-width: 320px;</span></span>
<span class="line"><span>    --gutter: 1rem;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns:</span></span>
<span class="line"><span>        minmax(var(--gutter), 1fr)</span></span>
<span class="line"><span>        minmax(</span></span>
<span class="line"><span>          min(var(--limit-min-container-width), 100% - var(--gutter) * 2),</span></span>
<span class="line"><span>          var(--limit-max-container-width)</span></span>
<span class="line"><span>        )</span></span>
<span class="line"><span>        minmax(var(--gutter), 1fr);</span></span>
<span class="line"><span>    row-gap: var(--gutter);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.container &gt; * {</span></span>
<span class="line"><span>    grid-column: 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.container .full__bleed {</span></span>
<span class="line"><span>    grid-column: 1 / -1;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6d063337c2a49ec8eaf06df9110a258~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/vYrxErN" target="_blank" rel="noreferrer">https://codepen.io/airen/full/vYrxErN</a></p></blockquote><p>我们只需要将上面的代码稍微调整一下，就可以基于子网格 <code>subgrid</code> 的功能来实现 Full-Bleed 布局。比如：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.container {</span></span>
<span class="line"><span>    --limit-max-container-width: 1024px;</span></span>
<span class="line"><span>    --limit-min-container-width: 320px;</span></span>
<span class="line"><span>    --gutter: 1rem;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns:</span></span>
<span class="line"><span>        [fullbleed-start] minmax(var(--gutter), 1fr)</span></span>
<span class="line"><span>        [main-start]</span></span>
<span class="line"><span>        minmax(</span></span>
<span class="line"><span>          min(var(--limit-min-container-width), 100% - var(--gutter) * 2),</span></span>
<span class="line"><span>          var(--limit-max-container-width)</span></span>
<span class="line"><span>        )</span></span>
<span class="line"><span>        [main-end]</span></span>
<span class="line"><span>        minmax(var(--gutter), 1fr)</span></span>
<span class="line"><span>        [fullbleed-end];</span></span>
<span class="line"><span>    row-gap: var(--gutter);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.container &gt; * {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.container &gt; * {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.full__bleed,</span></span>
<span class="line"><span>.full__bleed &gt; * {</span></span>
<span class="line"><span>    grid-column: fullbleed;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br></div></div><p>示例中，在 <code>grid-template-columns</code> 定义网格轨道的时候，也显式给网格线命名。<code>.container</code> 容器中所有子元素都被定义为一个子网格，并且 <code>grid-template-columns</code> 设置为 <code>subgrid</code> 。我们都知道，子网格会继承父网格所有特性，你可以使用已命名好的网格线名称来放置网格项目：</p><ul><li>除全宽（百分百宽度）的元素 <code>.full__bleed</code> 之外的其他元素都被放置在 <code>main-start / main-end</code> 列；</li><li>全宽（百分百宽度）的元素 <code>.full__bleed</code> 放置在 <code>fullbleed-start / fullbleed-end</code> 列。</li></ul><p>加上 <code>.container</code> 所有子元素的 <code>display</code> 属性值设置为 <code>inherit</code> ，因此它们都是一个网格（是 <code>.container</code> 网格的子网格），所以它们的子元素，比如 <code>.full__bleed</code> 的子元素 <code>img</code> 也是网格项目。它们都是全宽，即 <code>fullbleed-start / fullbleed-end</code> 。</p><p>使用子网格和直接使用网格构建出来的 Full-Bleed 布局效果是一样的：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/10eff151fd6b4b148fe04ac06a03359d~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/gOKmbQL" target="_blank" rel="noreferrer">https://codepen.io/airen/full/gOKmbQL</a></p></blockquote><p>有了这个基础，我们就可以来看子网格构建“百分百宽度的条纹布局”了。把 HTML 结构调整一下：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;container&quot;&gt;</span></span>
<span class="line"><span>  &lt;h1&gt;百分百宽度的条纹布局（Subgrid）&lt;/h1&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that a ...&lt;/p&gt;</span></span>
<span class="line"><span>  &lt;section class=&quot;full__bleed fullwidth&quot;&gt;</span></span>
<span class="line"><span>    &lt;img src=&quot;&quot; width=&quot;2568&quot; height=&quot;600&quot; alt=&quot;&quot; /&gt;</span></span>
<span class="line"><span>  &lt;/section&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that ...&lt;/p&gt;</span></span>
<span class="line"><span>  &lt;section class=&quot;full__bleed left&quot;&gt;</span></span>
<span class="line"><span>    &lt;img src=&quot;&quot; width=&quot;2568&quot; height=&quot;600&quot; alt=&quot;&quot; /&gt;</span></span>
<span class="line"><span>  &lt;/section&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that ...&lt;/p&gt;</span></span>
<span class="line"><span>  &lt;section class=&quot;full__bleed right&quot;&gt;</span></span>
<span class="line"><span>    &lt;img src=&quot;&quot; width=&quot;2568&quot; height=&quot;600&quot; alt=&quot;&quot; /&gt;</span></span>
<span class="line"><span>  &lt;/section&gt;</span></span>
<span class="line"><span>  &lt;p&gt;Meaning that ...&lt;/p&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><p>我们可以像下图这样来定义网格：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2bd27b363f8644eda92ddcb51cac7004~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>正如你所看到的：</p><ul><li>网格第一列和最后一列是一个较小的空白间距，相当于间距一样，比如说 <code>1rem</code>；</li><li>网格第二列和第四列是相等的，占用容器的可用空间，可以使用 <code>fr</code> 单位值来定义，我们这里设置为 <code>minmax(0, 1fr)</code>；</li><li>网格第三列（中间列），它是用来放置居中内容的一列，为了更好地适配不同终端的浏览器屏幕的尺寸，可以将 <code>minmax()</code> 和 <code>min()</code> 函数结合起来使用，比如 <code>minmax(min(var(--limit-min-container-width), 100% - var(--gutter) * 2),var(--limit-max-container-width))</code></li></ul><p>具体代码如下：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.container {</span></span>
<span class="line"><span>    --limit-max-container-width: 960px;</span></span>
<span class="line"><span>    --limit-min-container-width: 320px;</span></span>
<span class="line"><span>    --gutter: 1rem;</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns:</span></span>
<span class="line"><span>        [fullwidth-start]</span></span>
<span class="line"><span>        var(--gutter)</span></span>
<span class="line"><span>        [left-start]</span></span>
<span class="line"><span>        minmax(0, 1fr)</span></span>
<span class="line"><span>        [main-start right-start]</span></span>
<span class="line"><span>        minmax(</span></span>
<span class="line"><span>          min(var(--limit-min-container-width), 100% - var(--gutter) * 2),</span></span>
<span class="line"><span>          var(--limit-max-container-width)</span></span>
<span class="line"><span>        )</span></span>
<span class="line"><span>        [main-end left-end]</span></span>
<span class="line"><span>        minmax(0, 1fr)</span></span>
<span class="line"><span>        [right-end]</span></span>
<span class="line"><span>        var(--gutter)</span></span>
<span class="line"><span>        [fullwidth-end];</span></span>
<span class="line"><span>  row-gap: var(--gutter);</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br></div></div><p>和实现 Full-Bleed 布局示例一样，把网格容器 <code>.container</code> 的所有子元素（所有网格项目）设置为子网格，并且显式设置 <code>grid-template-columns</code> 的值为 <code>subgrid</code> ：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.container &gt; * {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f1b343aaef8943f4a45949c7d3df1f64~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>这样，你就可以使用网格线名称，将网格项目放置到相应的位置，完成最终所需要的布局效果：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.container &gt; *:not(.full__bleed) {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.full__bleed.fullwidth {</span></span>
<span class="line"><span>    grid-column: fullwidth;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.fullwidth img {</span></span>
<span class="line"><span>    grid-column: fullwidth;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.fullwidth figcaption {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span>    justify-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.full__bleed.left {</span></span>
<span class="line"><span>    grid-column: left;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.left &gt; img {</span></span>
<span class="line"><span>    grid-column: left;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.left &gt; figcaption {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span>    justify-self: end;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.full__bleed.right {</span></span>
<span class="line"><span>    grid-column: right;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.right &gt; img {</span></span>
<span class="line"><span>    grid-column: right;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.right &gt; figcaption {</span></span>
<span class="line"><span>    grid-column: main;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br></div></div><p>最终效果如下：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/721b53c9f1034ce984799df277ae29d3~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/ZEReYVq" target="_blank" rel="noreferrer">https://codepen.io/airen/full/ZEReYVq</a></p></blockquote><p>注意，你也可以在上面示例基础上进一步加工，实现下图这样的布局效果：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8ce60203dffd4b78ba92f17f55352ed8~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>就当上图是个小作业，感兴趣的同学不妨试一试，看看你能用多少种布局方案实现上图的布局效果。</p><h2 id="时间轴-timeline-组件" tabindex="-1">时间轴（Timeline）组件 <a class="header-anchor" href="#时间轴-timeline-组件" aria-label="Permalink to &quot;时间轴（Timeline）组件&quot;">​</a></h2><p>时间轴卡片组件也是 Web 中常见的一种设计，我们可以在上面的“百分百宽度的条纹布局”技术方案的基础上来构建时间轴卡片组件。</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/05ed74596f6d4812be9a29d6018f3948~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>使用网格和子网格，再借助 CSS 媒体查询，你就可以很轻易构建出上图所示的时间轴卡片组件。</p><ul><li>当浏览器视窗宽度大于 <code>768px</code> ，卡片在时间轴上是错开排列的，单数居右，双数居中；</li><li>当浏览器视窗宽度小于 <code>768px</code> ，卡片在块轴方向垂直排列。</li></ul><p>另外，每张卡片的数字指示器，都能和卡片的标题垂直对齐：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24e5367e137b47e2bdcc4818a269ad01~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址：<a href="https://codepen.io/airen/full/KKeWVNq" target="_blank" rel="noreferrer">https://codepen.io/airen/full/KKeWVNq</a></p></blockquote><p>上图所示的时间轴卡片组件所需的 HTML 的结构可能会像下面这样：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;timeline&quot;&gt;</span></span>
<span class="line"><span>    &lt;!-- 卡片容器 --&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;card--wrapper&quot;&gt;</span></span>
<span class="line"><span>        &lt;!-- 每张卡片的 HTML 结构 --&gt;</span></span>
<span class="line"><span>        &lt;div class=&quot;card&quot;&gt;</span></span>
<span class="line"><span>            &lt;h3 class=&quot;title&quot;&gt;卡片标题&lt;/h3&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;card__content&quot;&gt;</span></span>
<span class="line"><span>                &lt;p&gt;卡片描述内容&lt;/p&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;!-- 卡片脚部 --&gt;</span></span>
<span class="line"><span>            &lt;blockquote&gt;</span></span>
<span class="line"><span>                &lt;svg viewBox=&quot;0 0 512 512&quot; width=&quot;80&quot; title=&quot;quote-left&quot; class=&quot;quote-icon&quot;&gt;</span></span>
<span class="line"><span>                  &lt;path d=&quot;M46...&quot; fill=&quot;currentColor&quot; /&gt;</span></span>
<span class="line"><span>                &lt;/svg&gt;</span></span>
<span class="line"><span>                &lt;p&gt;Dolor ce...&lt;/p&gt;</span></span>
<span class="line"><span>            &lt;/blockquote&gt;</span></span>
<span class="line"><span>        &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>    &lt;!-- 省略其他卡片的 HTML 结构 --&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><p>对于构建上图这样的响应式时间轴卡片组件，我们遵循<strong>移动端先行</strong>的原则，即：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f0b18e99b46a41ea86b7a13f767bc876~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>你已经看到了，时间轴卡片组件的<strong>轴和卡片的数字指示器</strong>都在卡片的左侧，这样一来：</p><ul><li>轴和卡片的数字指示器都在第一列；</li><li>卡片在第二列。</li></ul><p>所以，我们可以在 <code>.timeline</code> 中创建一个两列网格，第一列是用来放置轴和卡片数字指示器的，你可以考虑设定，比如 <code>4rem</code> ，第二列可以把网格的可用空间（除第一列和列间距之外的空间）都留给卡片，可以设置 <code>1fr</code> ：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.timeline {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns: minmax(4rem, max-content) 1fr;</span></span>
<span class="line"><span>    gap: 2rem 4px;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/19582dcd1e8e4bc7978fc1365c8059e7~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>按照网格项目放置的方法，将时间轴和卡片放置到指定的位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.timeline::before {</span></span>
<span class="line"><span>    grid-column: 1 / 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card--wrapper {</span></span>
<span class="line"><span>    grid-column: 1 / 3;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>注意，示例中的轴线（上图中的“白色竖条”）使用了 <code>.timeline</code> 的伪元素 <code>::before</code> 绘制的，为了让 HTML 结构更简洁以及少嵌套一层子网格，对于时间轴的轴线采用了绝对定位，看上去就像是跨越了网格 <code>.timeline</code> 的所有行：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.timeline::before {</span></span>
<span class="line"><span>    /* 将时间轴线放置在 timeline 网格的第一列中 */</span></span>
<span class="line"><span>    grid-column: 1 / 2;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 绘制时间轴线 */</span></span>
<span class="line"><span>    content: &quot;&quot;;</span></span>
<span class="line"><span>    width: 10px;</span></span>
<span class="line"><span>    background-color: #fff;</span></span>
<span class="line"><span>    border-radius: 5px;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 采用绝对定位，让时间轴线跨越 timeline 网格的所有行, 并采用绝对定位，让其水平居中 */</span></span>
<span class="line"><span>    position: absolute;</span></span>
<span class="line"><span>    top: 0;</span></span>
<span class="line"><span>    bottom: 0;</span></span>
<span class="line"><span>    left: 50%;</span></span>
<span class="line"><span>    transform: translateX(-50%);</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>不难发现，每张卡片都有两个部分组成，即<strong>卡片数字指示器</strong>和<strong>卡片自身</strong>， 而且卡片数字指示器也是放在第一列，和时间轴线重叠在一起。所以，我们可以将 <code>.card--wrapper</code> 也定义为一个网格，并且继承其父网格 <code>.timeline</code> 的列网格轨道数量和尺寸，即设置 <code>grid-template-columns</code> 的值为 <code>subgrid</code> ：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card--wrapper {</span></span>
<span class="line"><span>    grid-column: 1 / 3;</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/169386e8a3ad47be9e6b00bf742e01d8~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>这样你就可以使用网格线，将卡片数字指示器 <code>.card--wrapper::before</code> 和卡片 <code>.card</code> 放置到指定的位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card--wrapper::before {</span></span>
<span class="line"><span>    grid-column: 1 / 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.card {</span></span>
<span class="line"><span>    grid-column: 2;</span></span>
<span class="line"><span>    grid-row: span 3;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><blockquote><p>特别声明，示例中的卡片数字指示器使用的是 CSS 的计算数器相关特性 <code>counter-reset</code> 、<code>counter-increment</code> 、<code>counter()</code> 和 CSS 伪元素自动生成的。这方面的内容已超出我们这个小册介绍的范围，感兴趣的同学请查阅示例相关源码！</p></blockquote><p>为了让卡片计数器能和卡片标题始终保持垂直对齐，还需要进一步将 <code>.card</code> 也定义为子网格，并且需要将它的 <code>grid-template-rows</code> 设置为 <code>subgrid</code> ：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.card--wrapper::before {</span></span>
<span class="line"><span>    grid-column: 1 / 2;</span></span>
<span class="line"><span>    align-self: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.card {</span></span>
<span class="line"><span>    grid-column: 2;</span></span>
<span class="line"><span>    grid-row: span 3;</span></span>
<span class="line"><span>  </span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>离目标越来越近了，只需要使用媒体查询 <code>@media</code> 在浏览器视窗宽度大于 <code>768px</code> 的条件下，重新定义父网格 <code>.timelne</code> 的列网格轨道的数量和尺寸，并且调整卡时间轴线、卡片数字指示器和卡片的位置，就可以完成最终想要的效果：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>@media only screen and (min-width: 768px) {</span></span>
<span class="line"><span>    /* 将网格列调整为三列 */</span></span>
<span class="line"><span>    .timeline {</span></span>
<span class="line"><span>        grid-template-columns: 1fr minmax(4rem, max-content) 1fr;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 时间轴线放置在第二列中 */</span></span>
<span class="line"><span>    .timeline::before {</span></span>
<span class="line"><span>        grid-column: 2 / 3;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 奇数卡片容器从第二列开始，并且跨越两列 */</span></span>
<span class="line"><span>    .card--wrapper:nth-of-type(2n + 1) {</span></span>
<span class="line"><span>        grid-column: 2 / span 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 偶数卡片容器从第一列开始，也跨越两列 */</span></span>
<span class="line"><span>    .card--wrapper:nth-of-type(2n) {</span></span>
<span class="line"><span>        grid-column: 1 / span 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>    /* 偶数卡片放置在第一列 */</span></span>
<span class="line"><span>    .card--wrapper:nth-of-type(2n) .card {</span></span>
<span class="line"><span>        grid-column: 1;</span></span>
<span class="line"><span>        grid-row: 1 / span 3;</span></span>
<span class="line"><span>    </span></span>
<span class="line"><span>        /* 偶数卡片其他样式的微调整 */</span></span>
<span class="line"><span>        filter: drop-shadow(-6px 6px 0px black);</span></span>
<span class="line"><span>        margin-left: 0;</span></span>
<span class="line"><span>        margin-right: 0.8rem;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 调整偶数卡片三角指向标的位置 */</span></span>
<span class="line"><span>    .card--wrapper:nth-of-type(2n) .title::after {</span></span>
<span class="line"><span>        right: auto;</span></span>
<span class="line"><span>        left: calc(100% - 15px);</span></span>
<span class="line"><span>        transform: translateY(-50%) rotate(-135deg);</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    /* 调整偶数卡片数字指示器位置 */</span></span>
<span class="line"><span>    .card--wrapper:nth-of-type(2n)::before {</span></span>
<span class="line"><span>        grid-column: 2 / 3;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2103dcd6f9f64f5db52bdd6062442254~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><h2 id="表单布局" tabindex="-1">表单布局 <a class="header-anchor" href="#表单布局" aria-label="Permalink to &quot;表单布局&quot;">​</a></h2><p>表单是 Web 中不可或缺的部分，因为 Web 需要用表单来和用户进行交流，所以将表单布局设计的好就显得尤为重要。比如下面这个登录表单：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c20e8654d3347d88d1e8924b09f0663~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>这是一个具有响应式能力的登录表单。暂且抛开其 UI 不谈，就只聊表单控件。在移动端上，布局相对较为简单，表单控件的标签 <code>&lt;label&gt;</code> 、表单控件（比如 <code>&lt;input&gt;</code>）、验证信息等都是垂直排列的。平板和桌面端，由于空间变大，更好地利用水平方向的空间，会把垂直排列的布局，调整为水平排列的布局，即 表单控件标签居左，表单控件和验证信息居右，甚至有的元素占两列，比如上图中的“登录按钮”。</p><p>另外，大多数构建表单一般会采用下面这样的 HTML 结构：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;form&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>        &lt;label for=&quot;id--name&quot;&gt;标签名&lt;/label&gt;</span></span>
<span class="line"><span>        &lt;input type=&quot;text&quot; id=&quot;id--name&quot; name=&quot;user-name&quot; placeholder=&quot;用户名&quot; /&gt;</span></span>
<span class="line"><span>        &lt;p class=&quot;control__help&quot;&gt;验证信息&lt;/p&gt;</span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/form&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>就上面的 HTML 的结构而言，要实现水平排列的布局是有难度的。即使是没有验证信息这一项，使用 Flexbox 布局也有一定的局限性，尤其是控件标签字数不同，你不得不在标签上 <code>label</code> 设置一个 <code>min-width</code> 值。</p><p>要是使用 CSS 网格来构建的话，就会方便很多，也不用担心标签控件字数，以及有没有其他的辅助元素，因为我们可以使用网格线名称，将元素放置到任意我们想要放置的位置。</p><p>接下来，就以上图为例，一起来看看怎么使用 CSS 网格和子网格实现所需要的表单布局。先来看 HTML 结构：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>&lt;div class=&quot;form--wrapper&quot;&gt;</span></span>
<span class="line"><span>    &lt;div class=&quot;form&quot;&gt;</span></span>
<span class="line"><span>        &lt;form&gt;</span></span>
<span class="line"><span>            &lt;h3&gt;登录&lt;/h3&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>                &lt;label for=&quot;user--name&quot;&gt;昵称：&lt;/label&gt;</span></span>
<span class="line"><span>                &lt;input type=&quot;text&quot; placeholder=&quot;请输入用户 ID&quot; name=&quot;user-name&quot; id=&quot;user--name&quot; /&gt;</span></span>
<span class="line"><span>                &lt;p&gt;用户 ID 不存在&lt;/p&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>                &lt;label for=&quot;user--password&quot;&gt;密码：&lt;/label&gt;</span></span>
<span class="line"><span>                &lt;input type=&quot;password&quot; placeholder=&quot;请输入登录密码&quot; name=&quot;user-password&quot; id=&quot;user--password&quot; /&gt;</span></span>
<span class="line"><span>                &lt;p&gt;密码输入错误&lt;/p&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>                &lt;label for=&quot;remember&quot;&gt;</span></span>
<span class="line"><span>                    &lt;input type=&quot;checkbox&quot; id=&quot;remember&quot; name=&quot;remember&quot;&gt;</span></span>
<span class="line"><span>                    请记住我!</span></span>
<span class="line"><span>                &lt;/label&gt;  </span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>                &lt;button&gt;登录&lt;/button&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>            &lt;div class=&quot;control&quot;&gt;</span></span>
<span class="line"><span>                &lt;label&gt;没有账号？&lt;a href=&quot;&quot;&gt;点击我注册&lt;/a&gt;&lt;/label&gt;</span></span>
<span class="line"><span>            &lt;/div&gt;</span></span>
<span class="line"><span>        &lt;/form&gt;</span></span>
<span class="line"><span>        &lt;figure&gt;</span></span>
<span class="line"><span>            &lt;img src=&quot;&quot; alt=&quot;封面图&quot; /&gt;</span></span>
<span class="line"><span>        &lt;/figure&gt;    </span></span>
<span class="line"><span>    &lt;/div&gt;</span></span>
<span class="line"><span>&lt;/div&gt;</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div><p>简单地分析一下，基于上面这个 HTML 结构，构建上图表单布局，可能会定义的网格有：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/17c33b5d1f0747a29e0d57e418e8260d~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><ul><li><code>body</code> 定义一个网格，主要用于整体的页面布局，构建一个 Full-Bleed 布局；</li><li><code>.form--wrapper</code> 定义一个网格，是构建表单 UI 主体布局，也是主网格；</li><li><code>.form</code> 是 <code>.form--wrapper</code> 的一个子网格，用于控制 <code>form</code> 和 <code>figure</code> 以及 <code>.form::before</code> 和 <code>.form::after</code> 四个网格项目的位置；</li><li><code>form</code> 重新定义一个网格，用于表单元素上的布局；</li><li><code>.control</code> 是 <code>form</code> 网格的子网格，控制表单标签、表单控件、验证信息等位置。</li></ul><p>接下来简单介绍一个涉及到布局的 CSS 代码。</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>body {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns: </span></span>
<span class="line"><span>        minmax(1rem, 1fr) </span></span>
<span class="line"><span>        minmax(min(100% - 2rem, 1134px), 1fr) </span></span>
<span class="line"><span>        minmax(1rem,1fr);</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>这段代码就不多说了，前面出现很多次了，即 Full-Bleed 布局代码。</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.form--wrapper {</span></span>
<span class="line"><span>    grid-column: 2 / 3;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: repeat(3, minmax(0, 1fr));</span></span>
<span class="line"><span>    grid-template-rows: repeat(3, auto);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.form {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>    margin: clamp(1rem, 2vw + 1.5rem, 3rem);</span></span>
<span class="line"><span>    z-index: 2;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span></span></span>
<span class="line"><span>    justify-items: center;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><p><code>.form</code> 网格是 <code>.form--wrapper</code> 网格的子网格，它继承了其父网格所有参数：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6234181631c54978acb6c62a0cfad323~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>在移动端下，网格项目都层叠在一起，如上图所示，整个表单 <code>&lt;form&gt;</code> 堆叠在图片 <code>&lt;figure&gt;</code> 之上。这在网格布局中是很容易就能做到的：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>.form &gt; * {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>.form::before,</span></span>
<span class="line"><span>.form::after {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>在平板和桌面端时，使用 CSS 媒体查询特性来调整 <code>.form</code> 网格的列轨道，并且将 <code>&lt;form&gt;</code> 和 <code>&lt;figure&gt;</code> 位置调整为水平排列，不再是堆叠在一起了：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dfae34b4f659486899e2d44f81decef3~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>@media only screen and (min-width: 768px) {</span></span>
<span class="line"><span>    .form {</span></span>
<span class="line"><span>        grid-template-columns: repeat(2, minmax(0, 1fr));</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form figure {</span></span>
<span class="line"><span>        grid-column: 1 / 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form::before,</span></span>
<span class="line"><span>    .form::after {</span></span>
<span class="line"><span>        grid-column: 1 / 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form &gt; form {</span></span>
<span class="line"><span>        grid-column: 2 / 3;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>使用同样的方法，分别将 <code>form</code> 和 <code>.control</code> 定义为网格。注意，这里的 <code>form</code> 网格只是 <code>.from</code> 网格的嵌套网格，它们是两个相互独立的网格，但 <code>.control</code> 网格却是 <code>form</code> 网格的子网格：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>form {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: max-content 1fr;</span></span>
<span class="line"><span>    gap: 1rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>    grid-row: span 3;</span></span>
<span class="line"><span>    gap: 0.25rem;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/891e6f508d5c42b59da552323a608339~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><p>根据网格线，将网格项目放置到指定位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>form &gt; * {</span></span>
<span class="line"><span>    grid-column: span 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control &gt; * {</span></span>
<span class="line"><span>    grid-column: 1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control:nth-last-child(-n + 3) {</span></span>
<span class="line"><span>    grid-row: span 1;</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>在桌面端时，调整相关的位置：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>@media only screen and (min-width: 1024px) {</span></span>
<span class="line"><span>    .control {</span></span>
<span class="line"><span>        grid-row: span 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; label {</span></span>
<span class="line"><span>        grid-column: 1;</span></span>
<span class="line"><span>        justify-self: end;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; input {</span></span>
<span class="line"><span>        grid-column: 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; p {</span></span>
<span class="line"><span>        grid-row: 2;</span></span>
<span class="line"><span>        grid-column: 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control:nth-last-child(3) &gt; label,</span></span>
<span class="line"><span>    .control:last-child &gt; label {</span></span>
<span class="line"><span>        grid-column: 1 / -1;</span></span>
<span class="line"><span>        justify-self: start;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    form h3 {</span></span>
<span class="line"><span>        justify-self: start;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><p>最终示例用到的布局代码：</p><div class="language- vp-adaptive-theme line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes light-plus one-dark-pro vp-code"><code><span class="line"><span>body {</span></span>
<span class="line"><span>    display: grid;</span></span>
<span class="line"><span>    grid-template-columns: </span></span>
<span class="line"><span>        minmax(1rem, 1fr) </span></span>
<span class="line"><span>        minmax(min(100% - 2rem, 1134px), 1fr) </span></span>
<span class="line"><span>        minmax(1rem,1fr);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form--wrapper {</span></span>
<span class="line"><span>    grid-column: 2 / 3;</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: repeat(3, minmax(0, 1fr));</span></span>
<span class="line"><span>    grid-template-rows: repeat(3, auto);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form--wrapper::before {</span></span>
<span class="line"><span>    grid-area: 1 / 3 / 2 / 4;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form--wrapper::after {</span></span>
<span class="line"><span>    grid-area: 3 / 1 / 4 / 3;</span></span>
<span class="line"><span>    align-self: end;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>    margin: clamp(1rem, 2vw + 1.5rem, 3rem);</span></span>
<span class="line"><span>    z-index: 2;</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    justify-items: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form &gt; * {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form::before,</span></span>
<span class="line"><span>.form::after {</span></span>
<span class="line"><span>    grid-area: 1 / 1 / -1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>form {</span></span>
<span class="line"><span>    width: 100%;</span></span>
<span class="line"><span>    z-index: 3;</span></span>
<span class="line"><span>    padding: clamp(1rem, 2vw + 1.5rem, 3rem);</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>figure {</span></span>
<span class="line"><span>    z-index: 1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.form::before {</span></span>
<span class="line"><span>    z-index: 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>form {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    place-content: center;</span></span>
<span class="line"><span>    grid-template-columns: max-content 1fr;</span></span>
<span class="line"><span>    gap: 1rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>form &gt; * {</span></span>
<span class="line"><span>    grid-column: span 2;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>form h3 {</span></span>
<span class="line"><span>    justify-self: center;</span></span>
<span class="line"><span>    margin-bottom: 2rem;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control {</span></span>
<span class="line"><span>    display: inherit;</span></span>
<span class="line"><span>    grid-template-columns: subgrid;</span></span>
<span class="line"><span>    grid-template-rows: subgrid;</span></span>
<span class="line"><span>    grid-row: span 3;</span></span>
<span class="line"><span>    gap: 0.25rem;</span></span>
<span class="line"><span>    align-items: center;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control &gt; * {</span></span>
<span class="line"><span>    grid-column: 1 / -1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>.control:nth-last-child(-n + 3) {</span></span>
<span class="line"><span>    grid-row: span 1;</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>@media only screen and (min-width: 768px) {</span></span>
<span class="line"><span>    .form {</span></span>
<span class="line"><span>        grid-template-columns: repeat(2, minmax(0, 1fr));</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form figure {</span></span>
<span class="line"><span>        grid-column: 1 / 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form::before,</span></span>
<span class="line"><span>    .form::after {</span></span>
<span class="line"><span>        grid-column: 1 / 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .form &gt; form {</span></span>
<span class="line"><span>        grid-column: 2 / 3;</span></span>
<span class="line"><span>        color: #333;</span></span>
<span class="line"><span>        text-shadow: none;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>    .control p {</span></span>
<span class="line"><span>        text-shadow: none;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>@media only screen and (min-width: 1024px) {</span></span>
<span class="line"><span>    .control {</span></span>
<span class="line"><span>        grid-row: span 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; label {</span></span>
<span class="line"><span>        grid-column: 1;</span></span>
<span class="line"><span>        justify-self: end;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; input {</span></span>
<span class="line"><span>        grid-column: 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control &gt; p {</span></span>
<span class="line"><span>        grid-row: 2;</span></span>
<span class="line"><span>        grid-column: 2;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    .control:nth-last-child(3) &gt; label,</span></span>
<span class="line"><span>    .control:last-child &gt; label {</span></span>
<span class="line"><span>        grid-column: 1 / -1;</span></span>
<span class="line"><span>        justify-self: start;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>​</span></span>
<span class="line"><span>    form h3 {</span></span>
<span class="line"><span>        justify-self: start;</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br><span class="line-number">111</span><br><span class="line-number">112</span><br><span class="line-number">113</span><br><span class="line-number">114</span><br><span class="line-number">115</span><br><span class="line-number">116</span><br><span class="line-number">117</span><br><span class="line-number">118</span><br><span class="line-number">119</span><br><span class="line-number">120</span><br><span class="line-number">121</span><br><span class="line-number">122</span><br><span class="line-number">123</span><br><span class="line-number">124</span><br><span class="line-number">125</span><br><span class="line-number">126</span><br><span class="line-number">127</span><br><span class="line-number">128</span><br><span class="line-number">129</span><br><span class="line-number">130</span><br><span class="line-number">131</span><br><span class="line-number">132</span><br><span class="line-number">133</span><br><span class="line-number">134</span><br><span class="line-number">135</span><br><span class="line-number">136</span><br><span class="line-number">137</span><br><span class="line-number">138</span><br><span class="line-number">139</span><br><span class="line-number">140</span><br><span class="line-number">141</span><br><span class="line-number">142</span><br><span class="line-number">143</span><br><span class="line-number">144</span><br><span class="line-number">145</span><br><span class="line-number">146</span><br></div></div><p>最终的效果如下图所示：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/92984e5b70f54a61a92242f9278811b2~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><blockquote><p>Demo 地址： <a href="https://codepen.io/airen/full/LYrWMwP" target="_blank" rel="noreferrer">https://codepen.io/airen/full/LYrWMwP</a></p></blockquote><h2 id="小结" tabindex="-1">小结 <a class="header-anchor" href="#小结" aria-label="Permalink to &quot;小结&quot;">​</a></h2><p>上面提到的示例只是使用子网格布局的几个常见的案例，事实上在 Web 布局中还有很多潜在的用例可以使用子网格来构建。简单地说，<strong>CSS 子网格将打开许多以前不可能的可能性</strong>。正如上面示例所展示的一样，在 CSS 子网格布局的基础上，你只需要添加一点点媒体查询的代码，就可以构建出适配更多终端平台的布局。</p><p>事实上，除了子网格和媒体查询结合之外，我们还可以使用容器查询和子网格一起来构建出组件式响应的布局。你将会感觉到，CSS 怎么能这么容易就实现了响应式布局。有关于这方面更详细的介绍，我们将在响应式布局的课程中与大家探讨。</p><p>心动不如行动，最后给大家布置一个小作业，请使用 CSS 子网格构建下图中天气组件的布局：</p><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/afff8ca9c9ec4cde8820b8a9250726cc~tplv-k3u1fbpfcp-zoom-1.image" alt="img"></p><h2 id="contributors" tabindex="-1">Contributors <a class="header-anchor" href="#contributors" aria-label="Permalink to &quot;Contributors&quot;">​</a></h2><div><section class="border-b-1 border-[var(--vp-c-divider)] w-full border-b-solid mt-[24px] pb-[12px] flex gap-[12px] mb-[12px] flex-wrap max-w-[85%]"><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 16 16" width="1.2em" height="1.2em"><path fill="currentColor" d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16m.847-8.145a2.502 2.502 0 1 0-1.694 0C5.471 8.261 4 9.775 4 11c0 .395.145.995 1 .995h6c.855 0 1-.6 1-.995c0-1.224-1.47-2.74-3.153-3.145"></path></svg> 作者:<span>Long Mo</span></div><!----><!----><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 16 16" width="1.2em" height="1.2em"><path fill="currentColor" d="M9.293 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.707A1 1 0 0 0 13.707 4L10 .293A1 1 0 0 0 9.293 0zM9.5 3.5v-2l3 3h-2a1 1 0 0 1-1-1zM5.485 6.879l1.036 4.144l.997-3.655a.5.5 0 0 1 .964 0l.997 3.655l1.036-4.144a.5.5 0 0 1 .97.242l-1.5 6a.5.5 0 0 1-.967.01L8 9.402l-1.018 3.73a.5.5 0 0 1-.967-.01l-1.5-6a.5.5 0 1 1 .97-.242z"></path></svg> 字数统计:<span>11.7k 字</span></div><div class="flex gap-[4px] items-center"><svg style="display:inline-block;" viewBox="0 0 20 20" width="1.2em" height="1.2em"><path fill="currentColor" d="M10 0a10 10 0 1 0 10 10A10 10 0 0 0 10 0zm2.5 14.5L9 11V4h2v6l3 3z"></path></svg> 阅读时长:<span>46 分钟</span></div></section></div><div class="flex gap-2 items-center"><a href="https://github.com/Longmo666" rel="noreferrer" target="_blank"><img src="https://github.com/Longmo666.png" class="w-8 h-8 rounded-full"></a> Long Mo</div><div class="px-[1.2rem] relative py-[1rem] border-1 border-[var(--vp-c-border)]/[.55] w-full min-h-[32px] border-solid mt-[32px] leading-[24px] rounded-[4px]"><svg style="display:inline-block;" viewBox="0 0 512 512" width="1.2em" height="1.2em" class="absolute top-[1rem] right-[1.2rem]"><path fill="currentColor" d="M256 512a256 256 0 1 0 0-512a256 256 0 1 0 0 512m-56.6-199.4c31.2 31.2 81.9 31.2 113.1 0c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9c-50 50-131 50-181 0s-50-131 0-181s131-50 181 0c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0c-31.2-31.2-81.9-31.2-113.1 0s-31.2 81.9 0 113.1z"></path></svg><section class="flex flex-col gap-y-[8px] overflow-hidden"><div><span class="font-bold">文章作者：</span><span><a href="https://github.com/Longmo666" rel="noreferrer" target="_blank">Long Mo</a></span></div><div><span class="font-bold">版权声明：</span><span> 本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noreferrer" target="_blank"> CC BY-NC-SA 4.0 </a> 许可协议。转载请注明来自 <a href="#" rel="noreferrer" target="_blank">Longmo Docs</a></span> ！ </div></section></div></div></div></main><footer class="VPDocFooter" data-v-e512d8d8 data-v-73a75ed6><!--[--><!--]--><div class="edit-info" data-v-73a75ed6><div class="edit-link" data-v-73a75ed6><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/xxx" target="_blank" rel="noreferrer" data-v-73a75ed6><!--[--><span class="vpi-square-pen edit-link-icon" data-v-73a75ed6></span> 在 github 上编辑此页<!--]--></a></div><div class="last-updated" data-v-73a75ed6><p class="VPLastUpdated" data-v-73a75ed6 data-v-28126c9f>上次更新: <time datetime="2024-03-04T16:28:46.000Z" data-v-28126c9f></time></p></div></div><nav class="prev-next" data-v-73a75ed6><div class="pager" data-v-73a75ed6><!----></div><div class="pager" data-v-73a75ed6><a class="VPLink link pager-link next" href="/long-press/css3/%E7%8E%B0%E4%BB%A3web%E5%B8%83%E5%B1%80/01" data-v-73a75ed6><!--[--><span class="desc" data-v-73a75ed6>下一篇</span><span class="title" data-v-73a75ed6>Web 布局技术演进：了解 Web 布局发展史</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-4c760b95 data-v-4f1388a4><div class="container" data-v-4f1388a4><!----><p class="copyright" data-v-4f1388a4>Copyright © 2024-present Longmo</p></div></footer><!--[--><!--]--></div></div>
    <script>window.__VP_HASH_MAP__=JSON.parse("{\"css3_lightningcss_index.md\":\"DvrpJ9-C\",\"css3_现代web布局_02.md\":\"NnFPbKjC\",\"css3_postcss_postcss-prefix-selector增加统一作用域.md\":\"BTi7xZ9T\",\"css3_现代web布局_01.md\":\"CSOVLYFa\",\"css3_index.md\":\"gWeubSHW\",\"css3_现代web布局_05.md\":\"XnHgE5qs\",\"css3_现代web布局_07.md\":\"B0JalRYm\",\"electron_electron开发实战_index.md\":\"DlTk4nHM\",\"css3_现代web布局_10.md\":\"QvmMy1qK\",\"css3_现代web布局_03.md\":\"DndCH4AP\",\"css3_现代web布局_22.md\":\"BTcBI1Ar\",\"css3_现代web布局_index.md\":\"BRrTkyN-\",\"react_antd使用踩坑经验汇总_procomponents_index.md\":\"CnA6aYv_\",\"nodejs_change-case更改大小写.md\":\"CtntdOEt\",\"react_react好用的插件_rxjs-hooks.md\":\"CahRrTvr\",\"nodejs_复制移动文件.md\":\"DJvz4Dcu\",\"css3_现代web布局_15.md\":\"CxTdKubj\",\"css3_现代web布局_06.md\":\"DKzKVbHi\",\"guide_axios封装.md\":\"yeyMeLKL\",\"react_react实战_设计模式与最佳实践_服务器端渲染（1）：基本套路.md\":\"Ci9ZteTc\",\"react_react实战_设计模式与最佳实践_react 单元测试.md\":\"ghuW9_Ym\",\"react_react好用的插件_react-to-print.md\":\"DUEXVCMF\",\"css3_现代web布局_12.md\":\"DzvNLnB9\",\"react_react好用的插件_react-load-script.md\":\"DBiqdA1k\",\"electron_electron开发实战_释放前端想象力.md\":\"DjfKiu2P\",\"react_react实战_设计模式与最佳实践_react的设计思想.md\":\"CDFxAnJB\",\"react_react组件库搭建指南_02开发调试.md\":\"C_T24zrV\",\"react_react实战_设计模式与最佳实践_react 的未来（1）： 拥抱异步渲染.md\":\"DDCdfFZA\",\"react_react实战_设计模式与最佳实践_react 状态管理（1）：组件状态.md\":\"CleS-bmU\",\"react_react好用的插件_react-viewer.md\":\"CK92G5ky\",\"electron_electron开发实战_electron应用打包.md\":\"DVihGNUt\",\"react_react好用的插件_index.md\":\"CYvYsgxN\",\"react_react好用的插件_formik-antd.md\":\"BVXoD1vi\",\"react_react实战_设计模式与最佳实践_组件设计模式（2）：高阶组件.md\":\"tcEHCkX9\",\"react_css解决方案_styled-components.md\":\"BdEVJSYP\",\"react_react后台管理系统项目实战_index.md\":\"Cf5Aki5e\",\"react_react好用的插件_floating-ui.md\":\"CJ47U607\",\"react_react好用的插件_js-pinyin.md\":\"CCi7zpiQ\",\"electron_electron开发实战_原生gui.md\":\"CKymHWIE\",\"react_antd使用踩坑经验汇总_tabs选项卡.md\":\"DbBQtB84\",\"react_react好用的插件_immer.md\":\"J3J2rLev\",\"css3_现代web布局_08.md\":\"CKAlv-cw\",\"react_react好用的插件_@ebay_nice-modal-react.md\":\"2t81QhzX\",\"react_react hooks.md\":\"DllmXlwe\",\"react_发布订阅_事件总线.md\":\"DGl0tyUU\",\"react_react组件库搭建指南_03编译打包.md\":\"BSWt83_X\",\"guide_quickstart.md\":\"DNtvLzj7\",\"react_开发一个组件库_如何完善组件单测.md\":\"9v27j5fA\",\"react_慕课网最新react技术栈，实战复杂低代码项目-仿问卷星_index.md\":\"DV2mTP-I\",\"react_ahooks_usewhydidyouupdate.md\":\"DeDGpqMK\",\"react_开发一个组件库_index.md\":\"DFCM9Fyc\",\"react_ahooks_usemutationobserver.md\":\"DopGRhup\",\"react_ahooks_uselocalstoragestate.md\":\"CNKG9DfH\",\"react_如何写出更优雅的 react 组件.md\":\"BNRAsuz5\",\"react_ahooks_useeventlistener.md\":\"C022IGRg\",\"react_ahooks_useloading.md\":\"hmNqPF-b\",\"react_ahooks_usethrottle.md\":\"Cxs7sHDg\",\"react_ahooks_usevirtuallist.md\":\"CbSqBIa_\",\"react_ahooks_index.md\":\"BZgeYQAN\",\"react_ahooks_usethrottleeffect.md\":\"Cu9lbAeN\",\"react_ahooks_useinterval.md\":\"z_JjaRUC\",\"react_ahooks_useinfinitescroll.md\":\"05X3BT3k\",\"react_ahooks_useboolean.md\":\"B9uk9pv1\",\"react_ahooks_usehover.md\":\"CQ90ygMl\",\"react_ahooks_usetoggle.md\":\"Dhg-kOcZ\",\"css3_现代web布局_16.md\":\"DqleGwZV\",\"electron_前端必学的桌面开发：electron_react开发桌面应用_1w多字超详细.md\":\"B4S71t_j\",\"react_index.md\":\"VMykJvDU\",\"react_ahooks_usethrottlefn.md\":\"h86SJGdz\",\"react_ahooks_useurlstate.md\":\"N0NRnJcE\",\"react_ahooks_usetrackedeffect.md\":\"DikGGrmT\",\"react_状态管理_natur.md\":\"CjabmgMv\",\"react_ahooks_useantdtable.md\":\"BRTEfq-4\",\"react_ahooks_userafinterval.md\":\"DbqchCta\",\"react_ahooks_useunmount.md\":\"DKpqgfJ2\",\"getting_index.md\":\"CslhLb_Q\",\"react_ahooks_usepagination.md\":\"BZPuA30r\",\"react_react好用的插件_react-jsx-parse.md\":\"BFws_Jvt\",\"react_ahooks_useprevious.md\":\"DoaMcKL0\",\"react_数据请求的reacthooks库_index.md\":\"BVjU5EHg\",\"nodejs_解压缩.md\":\"B8sDL8Ck\",\"react_开发一个组件库_handlebars模板.md\":\"eFtlYiJE\",\"react_自定义hooks_useasynceffect.md\":\"0TOcgDP8\",\"react_ahooks_usewebsocket.md\":\"BSCnKAhD\",\"css3_现代web布局_09.md\":\"CJg03gvR\",\"react_ahooks_useasynceffect.md\":\"LHnOKcnJ\",\"移动端项目_index.md\":\"BYabTvu-\",\"react_ahooks_usememoizedfn.md\":\"BHTS7A7g\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_index.md\":\"BOXXNcld\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第04章 ts 类易被忽视的重要技能，单件设计模式和相关技能深入.md\":\"CCgSUH_B\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第11章 运用 ts 手写 promise 源码.md\":\"BalHRnKD\",\"react_性能监控_index.md\":\"BLRO71Ft\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第03章 ts类方法代码优化的三大法宝： 函数重载、类方法重载、类构造器重载.md\":\"BS1BYvbm\",\"standard_fatherrc.ts配置文件.md\":\"Dkdjh5--\",\"react_自定义hooks_useexceldownload.md\":\"DGb3CWTU\",\"tools_runjs.md\":\"IzZ9xe5N\",\"tools_自动版本管理和生成changelog.md\":\"Dak6Id3b\",\"react_react实战_设计模式与最佳实践_路由的魔法：react router.md\":\"CZ2pkqmc\",\"tools_依赖镜像地址.md\":\"D5Etjm_v\",\"react_react实战_设计模式与最佳实践_组件设计模式（5）：组合组件.md\":\"D54UFiB5\",\"tools_workspaces核心特性总结.md\":\"CxNbObiL\",\"react_自定义hooks_usegreatasync.md\":\"DRVA9yrK\",\"react_react组件库搭建指南_05标准化发布流程.md\":\"BCCPnMto\",\"react_react实战_设计模式与最佳实践_组件设计模式（1）：聪明组件和傻瓜组件.md\":\"tHZI-Xkb\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第05章 ts继承深入_手写优化底层源码.md\":\"B3EQqYKB\",\"tools_rollup打包.md\":\"tSbCVBX5\",\"tools_webstorm快捷键.md\":\"wTpb7qJx\",\"react_react实战_设计模式与最佳实践_服务器端渲染（2）理解nextjs.md\":\"BqBtpEHC\",\"tools_vscode使用教程.md\":\"CqieXqJ8\",\"react_react最佳实践.md\":\"CG2Xrs5X\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第07章 泛型类_泛型接口_泛型类约束的复杂应用【无比重要的深度技能】.md\":\"CuEcP3SC\",\"react_自定义hooks_useeffectenhanced.md\":\"BSK0VwJa\",\"vue_index.md\":\"OW-QE8NS\",\"react_状态管理_react中的组件通信方案.md\":\"D8VvM0h8\",\"typescript_ts 从入门到深度掌握，晋级typescript高手实战课程_index.md\":\"CHFAmRtj\",\"standard_pretty-quick.md\":\"CL9LWL6Z\",\"typescript_ts 从入门到深度掌握，晋级typescript高手实战课程_第10章ts声明文件，ts模块.md\":\"BgUWX90K\",\"react_ahooks_usesetstate.md\":\"jYidiqGI\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第06章 ts高频使用技能： 类型断言、类型守卫、自定义守卫_ 多态_类型守卫组合应用.md\":\"DTiCfWrY\",\"standard_typings.d.ts.md\":\"COgkopwu\",\"react_react实战_设计模式与最佳实践_组件设计模式（4）：提供者模式.md\":\"CpJkLsBD\",\"typescript_axios_index.md\":\"CjiV2R0j\",\"css3_现代web布局_23.md\":\"DtcX9bTS\",\"electron_electron开发实战_app特性.md\":\"CCGKgh2J\",\"tools_常用命令.md\":\"BCECAPPN\",\"react_ahooks_useupdateeffect.md\":\"B8UnIDT1\",\"tools_npm镜像源管理工具.md\":\"BQvl6-cK\",\"react_自定义hooks_index.md\":\"TbSBlD7i\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第15章 js 原型_复杂原型继承 【查漏补缺】.md\":\"Bym60KVf\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第12章整合vue3手写高水准大厂的ts版vuex4源码.md\":\"Cb3ALa6o\",\"react_css解决方案_css_module.md\":\"kmxgfb6l\",\"css3_现代web布局_04.md\":\"qxIAivzd\",\"react_ahooks_useraftimeout.md\":\"zZ6X2MGp\",\"react_自定义hooks_usecopy.md\":\"B_vVrQah\",\"react_useform.md\":\"D7K5ezD8\",\"css3_现代web布局_27.md\":\"DVEkZdZW\",\"react_状态管理_valtio.md\":\"CXPGtt95\",\"typescript_tsup如何使用.md\":\"CHCfoXjX\",\"react_ahooks_usecookiestate.md\":\"CdRty31d\",\"tools_node各类命令.md\":\"Dp8hvkZX\",\"electron_electron开发实战_electron优化白屏.md\":\"TluuIOV8\",\"css3_现代web布局_24.md\":\"BTAj5AxQ\",\"css3_现代web布局_13.md\":\"BvIlMTco\",\"css3_现代web布局_14.md\":\"CXYZfM8r\",\"react_antd使用踩坑经验汇总_antdtable表格.md\":\"DJY5Mvdl\",\"guide_babel.md\":\"DTbGDSVq\",\"react_状态管理_zustand翻译文档.md\":\"D72s6MxU\",\"guide_index.md\":\"zNzT7elx\",\"tools_资源导航.md\":\"ByR0zpON\",\"react_antd使用踩坑经验汇总_menu菜单.md\":\"CUT3snoK\",\"tools_pnpm多包项目.md\":\"B5SWK1rS\",\"guide_webpack插件.md\":\"RycubFW9\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第02章 全栈思维全面深度掌握 ts 类.md\":\"DT7QMqkY\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第10章 从装饰器应用，底层 js 到 仿 nestjs实战，路由器底层复杂泛型.md\":\"D8kaCtfy\",\"electron_electron开发实战_开发一个简单版的番茄钟.md\":\"CrvCihNB\",\"react_ahooks_useclickaway.md\":\"CZiIOkBS\",\"index.md\":\"C-4ajOyn\",\"react_自定义hooks_useinterval.md\":\"CL7txl3c\",\"nodejs_请求工具类.md\":\"pJv1vv26\",\"react_ahooks_usedebouncefn.md\":\"DoBqhrGU\",\"getting_why.md\":\"B0La2IDF\",\"vue_vue2打包优化.md\":\"o7QF6PW3\",\"nodejs_globby.md\":\"CTH274g9\",\"standard_tsconfig.json.md\":\"CFCzGYxu\",\"react_reactrouter.md\":\"B9PtxEJ9\",\"typescript_ts-challenge.md\":\"CQjhG-Mq\",\"css3_现代web布局_18.md\":\"DbKppEVn\",\"react_ahooks_usedebounce.md\":\"DRqZkoSI\",\"react_自定义hooks_useintersection.md\":\"Bvd3uAWW\",\"nodejs_cli工具_index.md\":\"CGwLSUZ5\",\"react_react实战_设计模式与最佳实践_index.md\":\"C8mvV9MI\",\"tools_规范git代码提交信息.md\":\"BASOsPqX\",\"tools_windows测试ip端口.md\":\"DG6x0Mw8\",\"electron_electron开发实战_使用nodejs调用原生模块.md\":\"CRvmiRGG\",\"nodejs_kill-port跨平台解决端口占用问题.md\":\"BEoOmVOA\",\"css3_现代web布局_28.md\":\"jsAdcmE1\",\"react_react实战_设计模式与最佳实践_组件实践（1）：如何定义清晰可维护的接口.md\":\"C9ky0LxI\",\"react_react实战_设计模式与最佳实践_react 的未来（3）：函数化的 hooks.md\":\"CFPGDH01\",\"react_react组件库搭建指南_index.md\":\"DavlhH-3\",\"react_react避坑指南_usecallback_usememo.md\":\"DBJVYTaL\",\"standard_prettier.md\":\"B8zmNcDZ\",\"react_react实战_设计模式与最佳实践_组件设计模式（3）：render props 模式.md\":\"J6wo2neN\",\"standard_git提交规范.md\":\"BY6vFgPF\",\"css3_现代web布局_26.md\":\"BlwKd9DD\",\"react_redux.md\":\"BR83V68G\",\"nodejs_fs-extra文件系统扩展.md\":\"BeGbM1-y\",\"react_react组件库搭建指南_06dumi2.x的使用.md\":\"BovenX8E\",\"tools_github常用技巧.md\":\"DCwuF17j\",\"electron_数据持久缓存方案_electron-store.md\":\"6LHFkhuG\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第08章 深度掌握泛型函数、泛型函数重载【无比重要的深度技能】.md\":\"BvOBMPMd\",\"nodejs_semantic-release.md\":\"B_4_SZrq\",\"react_react实战_设计模式与最佳实践_组件实践（2）：组件的内部实现.md\":\"pvpT0TG5\",\"typescript_tslib如何使用.md\":\"BsoCW_pQ\",\"react_react实战_设计模式与最佳实践_组件实践（3）：组件化样式.md\":\"DGiADrWs\",\"react_css解决方案_index.md\":\"Q7QSPlYi\",\"typescript_tsdx使用.md\":\"Bcl_A70V\",\"css3_现代web布局_17.md\":\"BCxBKcNP\",\"react_react避坑指南_usestate.md\":\"DK9-NLHJ\",\"electron_react中开发踩坑.md\":\"DpZMxt4e\",\"react_react实战_设计模式与最佳实践_react 的未来（2）：suspense 带来的异步操作革命.md\":\"BLMrhryT\",\"guide_两个跨域页面进行跳转传参的终极方案.md\":\"DrhWeMH4\",\"react_react避坑指南_index.md\":\"DSoRNwmH\",\"react_自定义hooks_useinputhistory.md\":\"BzWdP5Ij\",\"react_ahooks_useeventemitter.md\":\"OluScTeX\",\"react_自定义hooks_usedebounce.md\":\"7ESFZNIZ\",\"electron_dll使用.md\":\"CGmPSJLR\",\"css3_现代web布局_19.md\":\"DIVJU0PC\",\"react_react好用的插件_react-fast-marquee.md\":\"ZhOvpApp\",\"guide_markdown语法.md\":\"BiAJoIJO\",\"nodejs_execa执行外部命令.md\":\"x2fLlbix\",\"nodejs_npkill快速查找删除node_modules.md\":\"CCmNiMZ0\",\"react_ahooks_usefullscreen.md\":\"BkgW8e5k\",\"react_自定义hooks_usesetparticalstate.md\":\"BUv_cnmS\",\"standard_css规范.md\":\"DeHg6jnS\",\"electron_数据持久缓存方案_数据持久缓存库lndb.md\":\"DJUK7UVx\",\"react_自定义组件_如何在react应用中建立错误处理层.md\":\"CNGgmToJ\",\"react_react搞定复杂项目状态管理_index.md\":\"BAj7---e\",\"typescript_晋级typescript高手，成为抢手的前端开发人才_第09章 深入infer、ts高级类型、泛型再进阶【全方位深度掌握 ts 泛型】.md\":\"C4bu5mph\",\"tools_idea 注释模板配置.md\":\"0gbuJbd6\",\"electron_基于electron-vite构建react桌面客户端.md\":\"DLOPvG7Q\",\"nodejs_release-it.md\":\"DMPaqLXc\",\"react_react实战_设计模式与最佳实践_react 状态管理（3）：mobx 使用模式.md\":\"Bm7xwY_i\",\"react_ahooks_usehistorytravel.md\":\"DiEJa1G5\",\"css3_现代web布局_21.md\":\"D2PeNBzk\",\"css3_现代web布局_11.md\":\"B10tI7m_\",\"react_antd使用踩坑经验汇总_tree组件.md\":\"CHpE5yvc\",\"electron_electron-builder.md\":\"DNL_pnq4\",\"standard_vue规范.md\":\"DyiLpRai\",\"electron_index.md\":\"BRqk3UrY\",\"react_自定义hooks_userouter.md\":\"LSydLgnY\",\"utils_rxjs.md\":\"C9QQC7cC\",\"standard_codereview代码审查.md\":\"vOhADmqT\",\"react_ahooks_userequest函数.md\":\"erWiB1Ub\",\"react_自定义hooks_usedebouncefn.md\":\"CD-kzD_X\",\"linux_linux常用命令.md\":\"D7RSIp22\",\"standard_commitlint.md\":\"Bc6BHMQJ\",\"react_自定义hooks_uselocationlisten.md\":\"lpoaVI0f\",\"standard_组件封装规范.md\":\"0Ow45yWm\",\"react_自定义hooks_useecharts.md\":\"GJwF9MkV\",\"nodejs_bluebird超高性能的promise库.md\":\"DY98ImvT\",\"react_react避坑指南_useref.md\":\"fBjuCQ9O\",\"electron_electron开发实战_electron环境搭建.md\":\"BaHlrXyB\",\"utils_index.md\":\"mk7T0j55\",\"react_自定义hooks_useevent.md\":\"Comn2-Er\",\"typescript_index.md\":\"Dcw9VPNE\",\"standard_git分支开发规范.md\":\"BIXsyTAc\",\"electron_三方库.md\":\"CAt92F-s\",\"react_react组件库搭建指南_01项目初始化.md\":\"hYE7GWll\",\"react_react好用的插件_jsbarcode.md\":\"CBTRcUAR\",\"electron_electron-react-boilerplate.md\":\"BzWSbABc\",\"react_自定义hooks_usemodal.md\":\"B_XFkn0G\",\"standard_editorconfig.md\":\"D8UrOG7b\",\"tools_git基本使用.md\":\"BvP_0S5g\",\"react_react避坑指南_闭包陷阱.md\":\"zChJGfX2\",\"standard_prettierrc.md\":\"BdHhuL9t\",\"standard_babelrc.md\":\"DxUrlX2l\",\"standard_eslint规范.md\":\"Mu3t4FWn\",\"react_react实战_设计模式与最佳实践_react 状态管理（4）：不同方式对比.md\":\"C3iD1iFV\",\"react_antd使用踩坑经验汇总_index.md\":\"DDsanD1T\",\"tools_yalc本地调试组件库方案.md\":\"BQ3H5AQN\",\"standard_json格式规范.md\":\"B3NuLvz_\",\"electron_配置讲解.md\":\"Bz4ASaED\",\"nodejs_index.md\":\"D6qsbk0v\",\"standard_node_cjs和esm混合开发.md\":\"DedlYZ1u\",\"css3_现代web布局_25.md\":\"DZBc6jqi\",\"standard_stylelint.md\":\"zaLGDP6-\",\"react_自定义hooks_useformmodal.md\":\"DRclMTXI\",\"standard_开源证书.md\":\"CNa1gXoD\",\"react_antd使用踩坑经验汇总_其他弹出层.md\":\"CYvGLZdo\",\"utils_baseinputnumber.md\":\"CCJr66pT\",\"guide_installation.md\":\"Cyna48DO\",\"utils_lodash.md\":\"B_LD-ulc\",\"standard_react规范.md\":\"BDzywc_U\",\"standard_sytlelint.md\":\"BHAGjA08\",\"tools_readme.md自动生成目录.md\":\"Doh9u-Eg\",\"react_自定义hooks_usememo.md\":\"CZgD0tn_\",\"standard_gitignore.md\":\"DGdE7Xq3\",\"react_react避坑指南_useeffect.md\":\"BNAb8N04\",\"nodejs_pkg打包node程序.md\":\"C_mVgg8Y\",\"standard_husky.md\":\"DWpB1fyF\",\"utils_calcutils.md\":\"QyONwp33\",\"tools_index.md\":\"CrRsxT5W\",\"standard_index.md\":\"zy5tYKLI\",\"react_自定义hooks_usemethods.md\":\"CLURCU9f\",\"react_自定义hooks_useloadscript.md\":\"CYcWRvSo\",\"tools_google快捷键.md\":\"mD76rDlK\",\"standard_package.json.md\":\"jsOo3MDQ\",\"standard_前端开发最佳实践总结.md\":\"BGrFiLKW\",\"react_自定义hooks_usesafestate.md\":\"m62ZMP2_\",\"standard_prettierignore.md\":\"VM68Ff5l\",\"react_react实战_设计模式与最佳实践_react 状态管理（2）：redux 使用模式.md\":\"CA0pcV96\",\"utils_mitt.md\":\"DG7F8qQl\",\"standard_gitlab.yml.md\":\"lN9PqoBe\",\"nodejs_minimist命令行参数解析.md\":\"Dx4gEgi2\",\"standard_命名规范.md\":\"DWUPIS4I\",\"react_自定义hooks_usepersistcallback.md\":\"FHXVMyDJ\",\"tools_windows终端优化.md\":\"DANvAyOj\",\"electron_ssl证书.md\":\"Q1dQBluF\",\"react_自定义组件_lazyload.md\":\"B9Bn4iLf\",\"react_自定义组件_keepalive.md\":\"YY9acXG_\",\"tools_常用node库.md\":\"DTeGhNPp\",\"standard_lint-staged.md\":\"DidcSpvQ\",\"css3_现代web布局_20.md\":\"DVP5FwHt\",\"guide_数字相关知识.md\":\"BRzTdbnI\",\"standard_圈复杂度.md\":\"B-UtHNKH\",\"tools_windows快捷键.md\":\"BFgiqO74\",\"standard_ts规范.md\":\"CiDbO0cg\",\"react_antd使用踩坑经验汇总_form表单.md\":\"DGT8jzsZ\",\"react_状态管理_zustand.md\":\"CQAFP37K\",\"react_react好用的插件_react-hook-form.md\":\"BsJSOnXN\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"龙陌的博客\",\"description\":\"基于vite为基础搭建的风格脚手架,提供多种模板以便于更高效的解决业务需求！\",\"base\":\"/long-press/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.ico\",\"nav\":[{\"text\":\"💻 首页\",\"link\":\"/\"},{\"text\":\"💡 指南\",\"link\":\"/guide/\",\"activeMatch\":\"/guide/\"},{\"text\":\"🔧 编程工具\",\"link\":\"/tools/\"},{\"text\":\"🔧 常用工具类\",\"link\":\"/utils/\"},{\"text\":\"📋 前端规范\",\"link\":\"/standard/\"},{\"text\":\"⭐ React\",\"link\":\"/react/React实战,设计模式与最佳实践/\"},{\"text\":\"⭐ TypeScript\",\"link\":\"/typescript/\"},{\"text\":\"⭐ Css3\",\"link\":\"/css3/\"},{\"text\":\"⭐ Electron\",\"link\":\"/electron/\"},{\"text\":\"⭐ Linux\",\"link\":\"/linux/linux常用命令\",\"activeMatch\":\"/linux/\"}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://vitepress.vuejs.org/guide/getting-started\"},{\"icon\":{\"svg\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" aria-hidden=\\\"true\\\" role=\\\"img\\\" width=\\\"20\\\" height=\\\"20\\\"  viewBox=\\\"0 0 512 512\\\" >\\n    <path fill=\\\"currentColor\\\" d=\\\"M488.6 104.1c16.7 18.1 24.4 39.7 23.3 65.7v202.4c-.4 26.4-9.2 48.1-26.5 65.1c-17.2 17-39.1 25.9-65.5 26.7H92.02c-26.45-.8-48.21-9.8-65.28-27.2C9.682 419.4.767 396.5 0 368.2V169.8c.767-26 9.682-47.6 26.74-65.7C43.81 87.75 65.57 78.77 92.02 78h29.38L96.05 52.19c-5.75-5.73-8.63-13-8.63-21.79c0-8.8 2.88-16.06 8.63-21.797C101.8 2.868 109.1 0 117.9 0s16.1 2.868 21.9 8.603L213.1 78h88l74.5-69.397C381.7 2.868 389.2 0 398 0c8.8 0 16.1 2.868 21.9 8.603c5.7 5.737 8.6 12.997 8.6 21.797c0 8.79-2.9 16.06-8.6 21.79L394.6 78h29.3c26.4.77 48 9.75 64.7 26.1zm-38.8 69.7c-.4-9.6-3.7-17.4-10.7-23.5c-5.2-6.1-14-9.4-22.7-9.8H96.05c-9.59.4-17.45 3.7-23.58 9.8c-6.14 6.1-9.4 13.9-9.78 23.5v194.4c0 9.2 3.26 17 9.78 23.5s14.38 9.8 23.58 9.8H416.4c9.2 0 17-3.3 23.3-9.8c6.3-6.5 9.7-14.3 10.1-23.5V173.8zm-264.3 42.7c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.2 6.3-14 9.5-23.6 9.5c-9.6 0-17.5-3.2-23.6-9.5c-6.1-6.3-9.4-14-9.8-23.2v-33.3c.4-9.1 3.8-16.9 10.1-23.2c6.3-6.3 13.2-9.6 23.3-10c9.2.4 17 3.7 23.3 10zm191.5 0c6.3 6.3 9.7 14.1 10.1 23.2V273c-.4 9.2-3.7 16.9-9.8 23.2c-6.1 6.3-14 9.5-23.6 9.5c-9.6 0-17.4-3.2-23.6-9.5c-7-6.3-9.4-14-9.7-23.2v-33.3c.3-9.1 3.7-16.9 10-23.2c6.3-6.3 14.1-9.6 23.3-10c9.2.4 17 3.7 23.3 10z\\\"></path>\\n  </svg>\"},\"link\":\"https://space.bilibili.com/248956095\"}],\"footer\":{\"copyright\":\"Copyright © 2024-present Longmo\"},\"sidebar\":{\"/\":[{\"text\":\"开始阅读\",\"collapsed\":false,\"items\":[{\"text\":\"阅读须知\",\"link\":\"/guide\"}]}],\"/tools/\":[{\"collapsed\":false,\"items\":[{\"text\":\"GitHub常用技巧\",\"link\":\"\\\\tools\\\\GitHub常用技巧.md\"},{\"text\":\"Google快捷键\",\"link\":\"\\\\tools\\\\Google快捷键.md\"},{\"text\":\"README.md自动生成目录\",\"link\":\"\\\\tools\\\\README.md自动生成目录.md\"},{\"text\":\"Rollup打包\",\"link\":\"\\\\tools\\\\Rollup打包.md\"},{\"text\":\"Runjs\",\"link\":\"\\\\tools\\\\Runjs.md\"},{\"text\":\"Vscode使用教程\",\"link\":\"\\\\tools\\\\Vscode使用教程.md\"},{\"text\":\"WebStorm快捷键\",\"link\":\"\\\\tools\\\\WebStorm快捷键.md\"},{\"text\":\"Windows快捷键\",\"link\":\"\\\\tools\\\\Windows快捷键.md\"},{\"text\":\"Windows测试IP端口\",\"link\":\"\\\\tools\\\\Windows测试IP端口.md\"},{\"text\":\"Windows终端优化\",\"link\":\"\\\\tools\\\\Windows终端优化.md\"},{\"text\":\"Yalc本地调试组件库方案\",\"link\":\"\\\\tools\\\\Yalc本地调试组件库方案.md\"},{\"text\":\"git基本使用\",\"link\":\"\\\\tools\\\\git基本使用.md\"},{\"text\":\"idea 注释模板配置\",\"link\":\"\\\\tools\\\\idea 注释模板配置.md\"},{\"text\":\"node各类命令\",\"link\":\"\\\\tools\\\\node各类命令.md\"},{\"text\":\"npm镜像源管理工具\",\"link\":\"\\\\tools\\\\npm镜像源管理工具.md\"},{\"text\":\"pnpm多包项目\",\"link\":\"\\\\tools\\\\pnpm多包项目.md\"},{\"text\":\"workspaces核心特性总结\",\"link\":\"\\\\tools\\\\workspaces核心特性总结.md\"},{\"text\":\"依赖镜像地址\",\"link\":\"\\\\tools\\\\依赖镜像地址.md\"},{\"text\":\"常用node库\",\"link\":\"\\\\tools\\\\常用node库.md\"},{\"text\":\"常用命令\",\"link\":\"\\\\tools\\\\常用命令.md\"},{\"text\":\"自动版本管理和生成CHANGELOG\",\"link\":\"\\\\tools\\\\自动版本管理和生成CHANGELOG.md\"},{\"text\":\"规范GIT代码提交信息\",\"link\":\"\\\\tools\\\\规范GIT代码提交信息.md\"},{\"text\":\"资源导航\",\"link\":\"\\\\tools\\\\资源导航.md\"}]}],\"/standard/\":[{\"collapsed\":false,\"items\":[{\"text\":\"CodeReview代码审查\",\"link\":\"\\\\standard\\\\CodeReview代码审查.md\"},{\"text\":\"Css规范\",\"link\":\"\\\\standard\\\\Css规范.md\"},{\"text\":\"Git分支开发规范\",\"link\":\"\\\\standard\\\\Git分支开发规范.md\"},{\"text\":\"Node_CJS和ESM混合开发\",\"link\":\"\\\\standard\\\\Node_CJS和ESM混合开发.md\"},{\"text\":\"React规范\",\"link\":\"\\\\standard\\\\React规范.md\"},{\"text\":\"babelrc\",\"link\":\"\\\\standard\\\\babelrc.md\"},{\"text\":\"commitlint\",\"link\":\"\\\\standard\\\\commitlint.md\"},{\"text\":\"editorconfig\",\"link\":\"\\\\standard\\\\editorconfig.md\"},{\"text\":\"eslint规范\",\"link\":\"\\\\standard\\\\eslint规范.md\"},{\"text\":\"fatherrc.ts配置文件\",\"link\":\"\\\\standard\\\\fatherrc.ts配置文件.md\"},{\"text\":\"gitignore\",\"link\":\"\\\\standard\\\\gitignore.md\"},{\"text\":\"gitlab.yml\",\"link\":\"\\\\standard\\\\gitlab.yml.md\"},{\"text\":\"git提交规范\",\"link\":\"\\\\standard\\\\git提交规范.md\"},{\"text\":\"husky\",\"link\":\"\\\\standard\\\\husky.md\"},{\"text\":\"json格式规范\",\"link\":\"\\\\standard\\\\json格式规范.md\"},{\"text\":\"lint-staged\",\"link\":\"\\\\standard\\\\lint-staged.md\"},{\"text\":\"package.json\",\"link\":\"\\\\standard\\\\package.json.md\"},{\"text\":\"prettier\",\"link\":\"\\\\standard\\\\prettier.md\"},{\"text\":\"prettierignore\",\"link\":\"\\\\standard\\\\prettierignore.md\"},{\"text\":\"prettierrc\",\"link\":\"\\\\standard\\\\prettierrc.md\"},{\"text\":\"pretty-quick\",\"link\":\"\\\\standard\\\\pretty-quick.md\"},{\"text\":\"stylelint\",\"link\":\"\\\\standard\\\\stylelint.md\"},{\"text\":\"sytlelint\",\"link\":\"\\\\standard\\\\sytlelint.md\"},{\"text\":\"tsconfig.json\",\"link\":\"\\\\standard\\\\tsconfig.json.md\"},{\"text\":\"ts规范\",\"link\":\"\\\\standard\\\\ts规范.md\"},{\"text\":\"typings.d.ts\",\"link\":\"\\\\standard\\\\typings.d.ts.md\"},{\"text\":\"vue规范\",\"link\":\"\\\\standard\\\\vue规范.md\"},{\"text\":\"前端开发最佳实践总结\",\"link\":\"\\\\standard\\\\前端开发最佳实践总结.md\"},{\"text\":\"命名规范\",\"link\":\"\\\\standard\\\\命名规范.md\"},{\"text\":\"圈复杂度\",\"link\":\"\\\\standard\\\\圈复杂度.md\"},{\"text\":\"开源证书\",\"link\":\"\\\\standard\\\\开源证书.md\"},{\"text\":\"组件封装规范\",\"link\":\"\\\\standard\\\\组件封装规范.md\"}]}],\"/aHooks/\":[],\"/utils/\":[{\"collapsed\":false,\"items\":[{\"text\":\"BaseInputNumber\",\"link\":\"\\\\utils\\\\BaseInputNumber.md\"},{\"text\":\"calcUtils\",\"link\":\"\\\\utils\\\\calcUtils.md\"},{\"text\":\"lodash\",\"link\":\"\\\\utils\\\\lodash.md\"},{\"text\":\"mitt\",\"link\":\"\\\\utils\\\\mitt.md\"},{\"text\":\"rxjs\",\"link\":\"\\\\utils\\\\rxjs.md\"}]}],\"/guide/\":[{\"text\":\"基础\",\"items\":[{\"text\":\"快速开始\",\"link\":\"/guide/quickstart\"},{\"text\":\"Markdown语法\",\"link\":\"/guide/Markdown语法\"}]},{\"text\":\"进阶\",\"items\":[{\"text\":\"打包指南\",\"link\":\"/guide/打包指南\"}]}],\"/react/\":{\"base\":\"/react/\",\"items\":[{\"text\":\"React基础\",\"base\":\"/react/\",\"collapsed\":false,\"items\":[{\"text\":\"Redux\",\"link\":\"Redux\"},{\"text\":\"React Hooks\",\"link\":\"React Hooks\"},{\"text\":\"ReactRouter\",\"link\":\"ReactRouter\"}]},{\"text\":\"Antd使用踩坑经验汇总\",\"base\":\"/react/Antd使用踩坑经验汇总/\",\"items\":[{\"text\":\"Form表单\",\"link\":\"Form表单\"},{\"text\":\"AntdTable表格\",\"link\":\"AntdTable表格\"},{\"text\":\"Tree树组件\",\"link\":\"Tree组件\"},{\"text\":\"其他弹出层\",\"link\":\"其他弹出层\"},{\"text\":\"Tabs选项卡\",\"link\":\"Tabs选项卡\"},{\"text\":\"Menu菜单\",\"link\":\"Menu菜单\"},{\"text\":\"Menu菜单\",\"link\":\"Menu菜单\"}]},{\"text\":\"CSS解决方案\",\"base\":\"/react/CSS解决方案/\",\"items\":[{\"text\":\"CSS Module\",\"link\":\"CSS_Module\"}]},{\"text\":\"ahooks\",\"link\":\"/aHooks/\"},{\"text\":\"自定义Hooks\",\"base\":\"/react/自定义Hooks/\",\"items\":[{\"text\":\"useRouter\",\"link\":\"useRouter\"},{\"text\":\"useLoadScript\",\"link\":\"useLoadScript\"},{\"text\":\"useInputHistory\",\"link\":\"useInputHistory\"},{\"text\":\"useSetParticalState\",\"link\":\"useSetParticalState\"},{\"text\":\"useFormModal\",\"link\":\"useFormModal\"},{\"text\":\"useCopy\",\"link\":\"useCopy\"},{\"text\":\"useIntersection\",\"link\":\"useIntersection\"},{\"text\":\"useModal\",\"link\":\"useModal\"},{\"text\":\"useInterval\",\"link\":\"useInterval\"},{\"text\":\"useModal\",\"link\":\"useModal\"},{\"text\":\"useModal\",\"link\":\"useModal\"}]},{\"text\":\"React实战：设计模式和最佳实践\",\"base\":\"/react/React实战,设计模式与最佳实践/\",\"collapsed\":true,\"items\":[{\"text\":\"React的设计思想\",\"link\":\"React的设计思想\"},{\"text\":\"组件实践（1）：如何定义清晰可维护的接口\",\"link\":\"组件实践（1）：如何定义清晰可维护的接口\"},{\"text\":\"组件实践（2）：组件的内部实现\",\"link\":\"组件实践（2）：组件的内部实现\"},{\"text\":\"组件实践（3）：组件化样式\",\"link\":\"组件实践（3）：组件化样式\"},{\"text\":\"组件设计模式（1）：聪明组件和傻瓜组件\",\"link\":\"组件设计模式（1）：聪明组件和傻瓜组件\"},{\"text\":\"组件设计模式（2）：高阶组件\",\"link\":\"组件设计模式（2）：高阶组件\"},{\"text\":\"组件设计模式（3）：render props 模式\",\"link\":\"组件设计模式（3）：render props 模式\"},{\"text\":\"组件设计模式（4）：提供者模式\",\"link\":\"组件设计模式（4）：提供者模式\"},{\"text\":\"组件设计模式（5）：组合组件\",\"link\":\"组件设计模式（5）：组合组件\"},{\"text\":\"React 单元测试\",\"link\":\"React 单元测试\"},{\"text\":\"React 状态管理（1）：组件状态\",\"link\":\"React 状态管理（1）：组件状态\"},{\"text\":\"React 状态管理（2）：Redux 使用模式\",\"link\":\"React 状态管理（2）：Redux 使用模式\"},{\"text\":\"React 状态管理（3）：Mobx 使用模式\",\"link\":\"React 状态管理（3）：Mobx 使用模式\"},{\"text\":\"React 状态管理（4）：不同方式对比\",\"link\":\"React 状态管理（4）：不同方式对比\"},{\"text\":\"路由的魔法：React Router\",\"link\":\"路由的魔法：React Router\"},{\"text\":\"服务器端渲染（1）：基本套路\",\"link\":\"服务器端渲染（1）：基本套路\"},{\"text\":\"服务器端渲染（2):理解Nextjs\",\"link\":\"服务器端渲染（2）理解NextJS\"},{\"text\":\"React 的未来（1）： 拥抱异步渲染\",\"link\":\"React 的未来（1）： 拥抱异步渲染\"},{\"text\":\"React 的未来（2）：Suspense 带来的异步操作革命\",\"link\":\"React 的未来（2）：Suspense 带来的异步操作革命\"},{\"text\":\"React 的未来（3）：函数化的 Hooks\",\"link\":\"React 的未来（3）：函数化的 Hooks\"}]},{\"text\":\"React搞定复杂项目状态管理\",\"base\":\"/react/React搞定复杂项目状态管理/\",\"collapsed\":false,\"items\":[]},{\"text\":\"React后台管理系统项目实战\",\"base\":\"/react/React后台管理系统项目实战/\",\"collapsed\":false,\"items\":[]},{\"text\":\"慕课网最新React技术栈，实战复杂低代码项目-仿问卷星\",\"base\":\"/react/慕课网最新React技术栈，实战复杂低代码项目-仿问卷星/\",\"collapsed\":false,\"items\":[]},{\"text\":\"React状态管理\",\"base\":\"/react/状态管理/\",\"collapsed\":false,\"items\":[{\"text\":\"zustand\",\"link\":\"zustand\"},{\"text\":\"zustand翻译文档\",\"link\":\"zustand翻译文档\"}]},{\"text\":\"开发一个组件库\",\"base\":\"/react/开发一个组件库/\",\"items\":[{\"text\":\"如何完善组件单测\",\"link\":\"如何完善组件单测\"},{\"text\":\"handlebars模板\",\"link\":\"handlebars模板\"}]},{\"text\":\"React好用的插件\",\"base\":\"/react/React好用的插件/\",\"items\":[{\"text\":\"js-pinyin\",\"link\":\"js-pinyin\"},{\"text\":\"jsbarcode\",\"link\":\"jsbarcode\"},{\"text\":\"react-jsx-parse\",\"link\":\"react-jsx-parse\"},{\"text\":\"react-load-script\",\"link\":\"react-load-script\"},{\"text\":\"react-to-print\",\"link\":\"react-to-print\"},{\"text\":\"react-viewer\",\"link\":\"react-viewer\"},{\"text\":\"react-hook-form\",\"link\":\"react-hook-form\"},{\"text\":\"react-window-infinite-loader\",\"link\":\"react-window-infinite-loader\"},{\"text\":\"react-window-infinite-loader\",\"link\":\"react-window-infinite-loader\"},{\"text\":\"react-window-infinite-loader\",\"link\":\"react-window-infinite-loader\"}]}]},\"/typescript/\":{\"base\":\"/typescript/\",\"items\":[{\"text\":\"TypeScript\",\"base\":\"/typescript/\",\"collapsed\":false,\"items\":[{\"text\":\"Redux\",\"link\":\"Redux\"}]},{\"text\":\"TS 从入门到深度掌握，晋级TypeScript高手实战课程\",\"base\":\"/typescript/TS 从入门到深度掌握，晋级TypeScript高手实战课程/\",\"collapsed\":false,\"items\":[{\"text\":\"第10章TS声明文件，TS模块.md\",\"link\":\"第10章TS声明文件，TS模块\"}]},{\"text\":\"晋级TypeScript高手，成为抢手的前端开发人才\",\"base\":\"/typescript/晋级TypeScript高手，成为抢手的前端开发人才/\",\"collapsed\":false,\"items\":[{\"text\":\"第07章 泛型类+泛型接口+泛型类约束的复杂应用【无比重要的深度技能】\",\"link\":\"第07章 泛型类+泛型接口+泛型类约束的复杂应用【无比重要的深度技能】\"},{\"text\":\"第08章 深度掌握泛型函数、泛型函数重载【无比重要的深度技能】\",\"link\":\"第08章 深度掌握泛型函数、泛型函数重载【无比重要的深度技能】\"},{\"text\":\"第09章 深入infer、TS高级类型、泛型再进阶【全方位深度掌握 TS 泛型】\",\"link\":\"第09章 深入infer、TS高级类型、泛型再进阶【全方位深度掌握 TS 泛型】\"},{\"text\":\"第08章 深度掌握泛型函数、泛型函数重载【无比重要的深度技能】\",\"link\":\"第08章 深度掌握泛型函数、泛型函数重载【无比重要的深度技能】\"}]}]},\"/css3/\":{\"base\":\"/css3/\",\"items\":[{\"text\":\"现代web布局\",\"base\":\"/css3/现代web布局/\",\"collapsed\":false,\"items\":[{\"text\":\"Web 布局技术演进：了解 Web 布局发展史\",\"link\":\"01\"},{\"text\":\"现代 Web 布局技术术语\",\"link\":\"02\"},{\"text\":\"Flexbox 布局基础使用\",\"link\":\"03\"},{\"text\":\"Flexbox 布局中的对齐方式\",\"link\":\"04\"},{\"text\":\"Flexbox 布局中的 flex 属性的基础运用\",\"link\":\"05\"},{\"text\":\"Flexbox 中的计算：通过扩展因子比例来扩展 Flex 项目\",\"link\":\"06\"},{\"text\":\"Flexbox 中的计算：通过收缩因子比例收缩 Flex 项目\",\"link\":\"07\"},{\"text\":\"Flexbox 布局中的 flex-basis：谁能决定 Flex 项目的大小？\",\"link\":\"08\"},{\"text\":\"使用 Flexbox 构建经典布局：10 种经典 Web 布局\",\"link\":\"09\"},{\"text\":\"10\",\"link\":\"10\"}]},{\"text\":\"postcss\",\"base\":\"/css3/postcss/\",\"collapsed\":false,\"items\":[{\"text\":\"postcss-prefix-selector增加统一作用域\",\"link\":\"postcss-prefix-selector增加统一作用域\"}]}]},\"/electron/\":{\"base\":\"/electron/\",\"items\":[{\"text\":\"electron开发实战\",\"base\":\"/electron/electron开发实战/\",\"collapsed\":false,\"items\":[{\"text\":\"Electron 环境搭建+前期准备\",\"link\":\"electron环境搭建\"},{\"text\":\"开发一个简单版的番茄钟\",\"link\":\"开发一个简单版的番茄钟\"},{\"text\":\"APP特性\",\"link\":\"App特性\"},{\"text\":\"原生GUI\",\"link\":\"原生GUI\"},{\"text\":\"使用NodeJs调用原生模块\",\"link\":\"使用NodeJs调用原生模块\"},{\"text\":\"释放前端想象力\",\"link\":\"释放前端想象力\"},{\"text\":\"Electron优化白屏\",\"link\":\"electron优化白屏\"},{\"text\":\"Electron应用打包\",\"link\":\"electron应用打包\"}]},{\"text\":\"Electron数据持久化方案\",\"base\":\"/electron/数据持久化方案/\",\"collapsed\":false,\"items\":[{\"text\":\"electron-store\",\"link\":\"electron-store\"},{\"text\":\"数据持久缓存库lndb\",\"link\":\"数据持久缓存库lndb\"}]},{\"text\":\"react中开发踩坑\",\"link\":\"/electron/react中开发踩坑\"}]}},\"outline\":{\"level\":[2,6],\"label\":\"本页目录\"},\"docFooter\":{\"prev\":\"上一篇\",\"next\":\"下一篇\"},\"lastUpdated\":{\"text\":\"上次更新\"},\"returnToTopLabel\":\"返回顶部\",\"darkModeSwitchLabel\":\"外观\",\"sidebarMenuLabel\":\"归档\",\"editLink\":{\"pattern\":\"https://github.com/xxx\",\"text\":\"在 github 上编辑此页\"},\"search\":{\"provider\":\"local\",\"options\":{\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"noResultsText\":\"无法找到相关结果\",\"resetButtonTitle\":\"清除查询条件\",\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\"}}}}}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
    
  </body>
</html>